fold中的函数参数的名称是什么


10

在高阶函数中,fold / reduce函数参数的名称(如果有)是什么?

我正在研究一个Monadic表格处理库,其中的行被折叠以产生简单的分析(例如查找列的最小,最大,平均值)。因此,我正在为fold函数的参数寻找一个合理的名称,并且在ML社区(或Haskell或Common Lisp作为第二和第三候选人)中公认的任何名称都将很有趣。

类似的名称ffold功能描述中很常见,但是它没有描述性,名词更适合。


10
没有一个。实际上,甚至没有一个通用名称来表示同形异像(fold)
Daniel Gratzer

2
如果这是学校作业或考试的问题,则需要从老师或教科书中获得答案,而不是从我们这里获得。他可能会说一些不同的话。课堂上教授的东西并不总是现实世界中常用的东西。
罗伯特·哈维

7
@RobertHarvey这不是考试题(?)或类似的东西。作为程序员,我认为为编程对象(类型,变量等)选择好名字非常重要。而且,如果某物具有众所周知的名称,那么除了无知之外,没有理由不使用它,这就是问题所在。
user40989 2013年

9
@Izkata不,那是不正确的。高阶函数是采用函数的函数。fold是高阶函数。fold的论证只是一个论点
Daniel Gratzer

1
@jozefg作为对您评论第二部分的回应。至于第一部分(和问题),请参阅我在Meta上的帖子。它们被称为过程参数。
2013年

Answers:


8

如@jozefg所述,我不知道对此是否有任何答案。因此,完全出于推测,这是一种可能的解释:

我怀疑原因是因为该类型(例如(a -> b -> b)Haskell的foldr类型中)比任何一个名字都有意义。由于aand b类型参数可以是任何东西,因此该函数还可以执行几乎所有操作。所以,你留下了类似的名字functioncombinermorphism,和argument,这是不是特别意义也不大。最好使用简短的,无干扰的名称。

另一个例子是id :: a -> a函数:您应该如何称呼它的参数?同样,我认为id'type'比其参数名称更具描述性。

但是,我同意您的看法-似乎应该在数学中使用通用名称。我希望有人可以对此进行纠正。


真实代码中其名称的一些示例:

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在数学(和函数式编程语言)中通常用作函数(gh)。

我们几乎一无所知f(通过设计,因为如果我们可以更详细地说明它,那么我们就不能使用fold太多东西),这个名称f告诉我们我们需要知道的所有内容,只是它是两个参数的函数。这个名字f很像英语中的代词“ it”,它是一个占位符,几乎可以代表任何含义。直到我们在句子中使用它,我们才知道它是什么,f并且直到我们打电话时,我们才知道它是什么fold

在命名事物时,我们希望从名称中获得尽可能多的信息,并且我们希望名称简短(如果我们可以在不牺牲重要信息的情况下获得名称)。在这里,我们有一个非常,它告诉我们近,我们知道它的一切简称。我认为无法对其进行改进。

在命令式编程中,i用作循环计数器(如果需要,还可以像j和一样k);在函数式编程中,f用于高阶函数中的函数自变量(g和和h,如果需要更多的话)。我对函数式语言没有足够的经验,无法确保f / g / h约定与i / j / k约定一样完善,但是如果不是,我认为应该这样(肯定是)建立在数学上)。


3

除了代词以外,我听说过的最常见的名称f是- binary operationbinary function比它更具体的问题是它实际上可以做任何事情,这就是为什么人们坚持使用类型签名a -> b -> a(或a -> b -> b正确折叠)的原因。

因此,我建议您严格执行该操作,坚持使用类型签名,幸运的是,特定的类型签名确实具有一个名称:binary function,就像a -> aa unary operationa -> ba一样unary function,您可以调用a -> a -> aa binary operationa -> b -> ca binary function


1
对我来说,binary operation这将意味着更多a -> a -> abinary function也将代表a -> b -> c……真理必定存在于两者之间。:-)
user40989 2014年

@ user40989好电话,已更正。
吉米·霍法

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.