Haskell fmap的参数太多

Haskell fmap的参数太多,haskell,functor,Haskell,Functor,第一个参数应为fmap,它是一个具有一个参数的函数 fmap :: Functor f => (a -> b) -> f a -> f b 然后我试着在序曲中说: Prelude> x = fmap (\x y -> x * y) 如您所见,fmap的第一个参数是一个函数,它有两个参数。为什么编译器让它通过 我传递给上面fmap的函数有两个参数,而不是一个 Haskell实际上没有包含多于(或少于)一个参数的函数。“双参数函数”实际上只是一个接受一个参数并

第一个参数应为
fmap
,它是一个具有一个参数的函数

fmap :: Functor f => (a -> b) -> f a -> f b
然后我试着在序曲中说:

Prelude> x = fmap (\x y -> x * y)
如您所见,
fmap
的第一个参数是一个函数,它有两个参数。为什么编译器让它通过


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

Haskell实际上没有包含多于(或少于)一个参数的函数。“双参数函数”实际上只是一个接受一个参数并生成另一个接受另一个参数的函数。也就是说,
\xy->x*y
只是
\x->\y->x*y
的语法捷径。这个概念被称为咖喱


这应该解释一下你的例子中发生了什么。您的
fmap
只需将数字的
f
转换为函数的
f
。因此,例如,
x[1,2,3]
将生成列表
[\y->1*y\y->2*y\y->3*y]
(也称
[(1*),(2*),(3*)]

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

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

Prelude> :t x
x :: (Functor f, Num a) => f a -> f (a -> a)
因此,
x
现在是一个函数,它接受一个应用于该函数的
a
函子作为输入,并返回一个类型的a元素,该类型的函子与
a->a
相同

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

Prelude> :t x [1,4,2,5]
x [1,4,2,5] :: Num a => [a -> a]
现在我们有一个函数列表,相当于:


因为,在Haskell中,所有函数都被认为是curried这是对算术的抽象,这在支持一类函数的语言中是可能的。与其关注多参数函数的算术性,还不如关注函数序列。这在Haskell应用程序中是非常常见的<代码>fxy
表示
fmap fxy
。例如,
(*)[2,3][5,7]
表示
[(2*),(3*)][5,7]
,其计算结果为
[2*5,2*7,3*5,3*7]
[10,14,15,21]
[\x -> 1*x, \x -> 4*x, \x -> 2*x, \x -> 5*x]