fmap

时间:2017-07-11 15:05:58

标签: haskell

第一个参数,fmap是预期的,是一个带有一个参数的函数。

fmap :: Functor f => (a -> b) -> f a -> f b

然后我尝试了前奏:

Prelude> x = fmap (\x y -> x * y)

如您所见,fmap的第一个参数是一个函数,它有两个参数。为什么编译器允许它通过?

我传递给上面fmap的函数有两个参数而不是一个!

2 个答案:

答案 0 :(得分:9)

Haskell实际上没有比一个参数更多(或更少)的函数。 “双参数函数”实际上只是一个函数,它接受一个参数并产生另一个带另一个参数的函数。也就是说,\x y -> x * y只是\x -> \y -> x * y的句法捷径。这个概念被称为currying。

所以这应该解释你的例子中发生了什么。您的fmap只会将f个数字转换为f个函数。因此,例如,x [1,2,3]会生成列表[\y -> 1 * y, \y -> 2 * y, \y -> 3 * y](a.k.a。[(1*), (2*), (3*)])。

答案 1 :(得分:2)

您已定义了一项功能。函数式编程的一个基本方面是函数可以是参数,存储到变量等等。

如果我们然后查询x类型,我们会得到:

Prelude> :t x
x :: (Functor f, Num a) => f a -> f (a -> a)

所以x现在是一个函数,它将 Functor作为输入,a应用于该函数,并返回一个类型的元素同一个仿函数,但应用了a -> a

因此,您可以在x应用列表,例如:

Prelude> :t x [1,4,2,5]
x [1,4,2,5] :: Num a => [a -> a]

现在我们有一个函数列表等效于

[\x -> 1*x, \x -> 4*x, \x -> 2*x, \x -> 5*x]