3

我不明白的是如何在haskell中以这种方式使用foldl。我不明白参数(在本例中为列表)是如何隐式传递的:

addAll :: [Int] -> Int
addAll =  foldl (+) 0

-- This is how I could write foldl to simplify addAll where xs is clearly defined

addAll :: [Int] -> Int
addAll xs = foldl (+) 0 xs

或者

addAll :: [Int] -> Int
addAll = \ xs -> foldl (+) 0 xs

但我真的不明白第一个例子。所以基本上我想知道如何在haskell中对某些东西进行评估?

4

2 回答 2

4

请记住,Haskell 中的所有函数都是柯里化的。foldl也不例外;它有 type Foldable t => (b -> a -> b) -> b -> t a -> b,这意味着它接受一个 type 的参数(b -> a -> b)并返回一个 type 的函数Foldable t => b -> t a -> b

该函数也是柯里化的。foldl (+)接受一个类型的参数Int b => b并返回一个类型的函数(Foldable t, Num b) => t b -> b

因此,foldl (+) 0has type (Foldable t, Num b) => t b -> b,并且您的类型注释做出了限制t ~ []and b ~ Int

于 2020-10-12T17:55:39.367 回答
4

但我真的不明白第一个例子。所以基本上我想知道如何在haskell中对某些东西进行评估?

foldl (+) 0产生一个函数。一个 type 的函数,(Foldable f, Num a) => f a -> a那你为什么需要一个额外的参数呢?addAll也是一个函数。

在函数式编程中,函数是“一等公民”。这意味着您可以将函数作为参数传递,并且结果可以是函数。在 Haskell 中,每个函数都只接受一个参数。确实:

foldl :: Foldable t => (b -> a -> b) ->  b ->  t a -> b

简称:

foldl :: Foldable t => (b -> a -> b) -> (b -> (t a -> b))

foldl因此 是一个函数,它接受一个类型的函数作为参数(b -> a -> b),并产生一个类型的函数b -> t a -> b。因此,这意味着foldl (+)具有类型:

foldl (+) :: (Foldable f, Num b) => b -> (f b -> b)

再次是一个函数,在这种情况下,它接受一个基本情况的参数foldl,然后返回一个映射 a 的函数(Foldable f, Num a) => f a -> f a。如果你写foldl (+) 0,这是因此的缩写(fold (+)) 0

于 2020-10-12T17:55:52.533 回答