foldの関数引数の名前は何ですか


10

高階関数に減らす/折りたたみがあれば、機能の引数の、名前は何か?

私は、単純な分析(列の最小値、最大値、平均値など)を生成するために行が折りたたまれているモナディックテーブル処理ライブラリに取り組んでいます。したがって、fold関数の引数の適切な名前と、MLコミュニティ(またはHaskellまたはCommon Lispの2番目と3番目の候補)で確立されている名前が興味深いものを探しています。

のような名前ffold関数の説明では一般的ですが、説明的ではなく、名詞の方が適しています。


10
ありません。実際、普遍的に使用されるカタモフィズムの名前すらありません(倍)
Daniel

2
これが学校の課題や試験の質問である場合は、私たちではなく、先生または教科書から回答を得る必要があります。彼はそれを別のものと呼ぶかもしれません。教室で教えられていることは、現実の世界で一般的に使用されているものとは限りません。
Robert Harvey

7
@RobertHarveyこれは試験問題(?)ではありません。プログラマーとして、プログラミングオブジェクト(型、変数など)に適切な名前を付けることは非常に重要だと思います。そして、何かがよく知られている名前を持っている場合、それを使用しない理由はありません—無知は別として、それが質問の目的です。
user40989 2013

9
@Izkataいいえ、不正解です。高階関数は、関数を取る関数です。fold高次関数です。折りたたみの議論は、まさにそれ、議論
Daniel Gratzer

1
@jozefgこれは、コメントの2番目の部分に対する応答です。最初の部分(および質問)については、メタに関する私の投稿を参照してください。これらは手続き型パラメーターと呼ばれます。
Izkata

回答:


8

@jozefgが述べたように、これに対する単一の答えがあるかどうかはわかりません。純粋に憶測から外れているので、考えられる理由の1つを次に示します。

-私はタイプので、理由がある疑い(a -> b -> b)Haskellのfoldr例は、 -を考え出すことができ、任意の名前の1以上の意味があります。以来aおよびb型パラメータは、可能性は何も、機能は同様にほとんど何でも行うことができます。あなたのような名前が残っているのでfunctioncombinermorphism、とargument、どちらかの特に意味がないです。短く、邪魔にならない名前を使用することもできます。

別の例はid :: a -> a関数です:あなたはその引数を何と呼ぶべきですか?繰り返しますが、idの型は引数の名前よりもわかりやすいと思います。

しかし、私はあなたに同意します-おそらく数学において、一般的な名前があるべきだと思われます。誰かがこれを訂正してくれることを願っています。


実際のコードでのその名前の例:

Haskellのライブラリ、それは主に呼ばれていますf(そして時にはoperatorコメントで):

class Foldable t where
    -- | Map each element of the structure to a monoid,
    -- and combine the results.
    foldMap :: Monoid m => (a -> m) -> t a -> m
    foldMap f = foldr (mappend . f) mempty

    -- | Right-associative fold of a structure.
    --
    -- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@
    foldr :: (a -> b -> b) -> b -> t a -> b
    foldr f z t = appEndo (foldMap (Endo . f) t) z

    -- | Right-associative fold of a structure, 
    -- but with strict application of the operator.
    foldr' :: (a -> b -> b) -> b -> t a -> b
    foldr' f z0 xs = foldl f' id xs z0
      where f' k x z = k $! f x z

    -- | Left-associative fold of a structure.
    --
    -- @'foldl' f z = 'Prelude.foldl' f z . 'toList'@
    foldl :: (a -> b -> a) -> a -> t b -> a
    foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z

    -- | Left-associative fold of a structure.
    -- but with strict application of the operator.
    --
    -- @'foldl' f z = 'List.foldl'' f z . 'toList'@
    foldl' :: (a -> b -> a) -> a -> t b -> a
    foldl' f z0 xs = foldr f' id xs z0
      where f' x k z = k $! f z x

    -- | A variant of 'foldr' that has no base case,
    -- and thus may only be applied to non-empty structures.
    --
    -- @'foldr1' f = 'Prelude.foldr1' f . 'toList'@
    foldr1 :: (a -> a -> a) -> t a -> a
    foldr1 f xs = fromMaybe (error "foldr1: empty structure")
                    (foldr mf Nothing xs)
      where
        mf x Nothing = Just x
        mf x (Just y) = Just (f x y)

    -- | A variant of 'foldl' that has no base case,
    -- and thus may only be applied to non-empty structures.
    --
    -- @'foldl1' f = 'Prelude.foldl1' f . 'toList'@
    foldl1 :: (a -> a -> a) -> t a -> a
    foldl1 f xs = fromMaybe (error "foldl1: empty structure")
                    (foldl mf Nothing xs)
      where
        mf Nothing y = Just y
        mf (Just x) y = Just (f x y)

-- instances for Prelude types

instance Foldable Maybe where
    foldr _ z Nothing = z
    foldr f z (Just x) = f x z

    foldl _ z Nothing = z
    foldl f z (Just x) = f z x

instance Ix i => Foldable (Array i) where
    foldr f z = Prelude.foldr f z . elems
    foldl f z = Prelude.foldl f z . elems
    foldr1 f = Prelude.foldr1 f . elems
    foldl1 f = Prelude.foldl1 f . elems

-- | Monadic fold over the elements of a structure,
-- associating to the right, i.e. from right to left.
foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
foldrM f z0 xs = foldl f' return xs z0
  where f' k x z = f x z >>= k

-- | Monadic fold over the elements of a structure,
-- associating to the left, i.e. from left to right.
foldlM :: (Foldable t, Monad m) => (a -> b -> m a) -> a -> t b -> m a
foldlM f z0 xs = foldr f' return xs z0
  where f' x k z = f z x >>= k

-- | Map each element of a structure to an action, evaluate
-- these actions from left to right, and ignore the results.
traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
traverse_ f = foldr ((*>) . f) (pure ())

-- | Map each element of a structure to a monadic action, evaluate
-- these actions from left to right, and ignore the results.
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
mapM_ f = foldr ((>>) . f) (return ())

f Clojureでも呼ばれています。

(def
    ^{:arglists '([f coll] [f val coll])
      :doc "f should be a function of 2 arguments. If val is not supplied,
  returns the result of applying f to the first 2 items in coll, then
  applying f to that result and the 3rd item, etc. If coll contains no
  items, f must accept no arguments as well, and reduce returns the
  result of calling f with no arguments.  If coll has only 1 item, it
  is returned and f is not called.  If val is supplied, returns the
  result of applying f to val and the first item in coll, then
  applying f to that result and the 2nd item, etc. If coll contains no
  items, returns val and f is not called."
      :added "1.0"}    
    reduce
     (fn r
       ([f coll]
             (let [s (seq coll)]
               (if s
                 (r f (first s) (next s))
                 (f))))
       ([f val coll]
          (let [s (seq coll)]
            (if s
              (if (chunked-seq? s)
                (recur f 
                       (.reduce (chunk-first s) f val)
                       (chunk-next s))
                (recur f (f val (first s)) (next s)))
              val)))))

6

fの関数引数の名前が悪いという考えには同意しませんfold。プログラミングで説明的な名前が必要な理由は、名前が何を表しているかを知るためであり、その名前fは数学(および関数型プログラミング言語)で関数(gおよびとして)に一般的に使用されhます。

私たちはほとんど何も知りませんf(設計により、より具体的になると、fold多くのことを使用することができなくなるため)。この名前fは、2つの引数の関数であることを除いて、知る必要があるすべてを示しています。この名前fは、英語の代名詞「it」によく似ています。これは、ほとんど何でも意味するプレースホルダーです。文中で使用するまでは「何」であるかわからないし、fを呼び出すまで何であるかわからないfold

物事に名前を付けるときは、名前からできるだけ多くの情報を取得する必要があります。重要な情報を犠牲にすることなく取得できる場合は、名前を短くすることをお勧めします。ここでは、私たちが知っているほとんどすべてを私たちに伝える非常に短い名前を持っています。改善できるとは思いません。

命令型プログラミングでiは、ループカウンターとして使用されます(必要に応じてjandとk同様)。関数型プログラミングでfは、高次関数の関数引数に使用されます(必要な場合はgandとh同様)。f / g / hの規則がi / j / kの規則と同様に確立されていることを確認するのに十分な関数型言語の経験はありませんが、確立されていない場合は、そうなるはずです(間違いなく数学で確立された)。


3

代名詞以外で私が聞いたこの最も一般的な名前fは、binary operationまたはbinary function-それよりも具体的であるという問題は、文字通り何でもできるということであり、それが人々が型シグネチャーに固執する理由ですa -> b -> a(またはa -> b -> bそれが正しい折りかどうか) 。

:あなたは幸いにも、特定の種類の署名が名前を持っていること、という型シグネチャにスティックを正確に行うことを提案している私はbinary function、同じようa -> aunary operation、とa -> bあるunary function、あなたが呼び出すことができると。a -> a -> abinary operationa -> b -> cbinary function


1
私にとってbinary operationはもっと意地悪でa -> a -> aありbinary functiona -> b -> c…真実は確かにその中間にあります。:-)
user40989 2014年

@ user40989良い呼び出し、修正されました。
ジミーホファ2014年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.