假设
f x y z = x*y*z
然后我希望与列表中的每个成员一起返回f的应用程序
foldl ($) f [1,2,3]
像(((f 1) 2) 3) = 1*2*3 = 6
函数f
将是累加器,并且折叠的每次迭代将应用一个参数并返回部分应用的函数作为下一个累加器。
为什么这不起作用?是因为f
在迭代时改变了类型吗?
顺便说一下:还有其他方法可以完成这种类型的功能应用吗?
答案 0 :(得分:6)
类型看起来像
foldl :: (a -> b -> a) -> a -> [b] -> a
($) :: (x -> y) -> x -> y
要将foldl
应用于($)
,需要将foldl
的第一个参数的类型与($)
进行匹配(技术上,统一)。也就是说,求解方程式
a -> b -> a = (x -> y) -> x -> y
这会立即导致
a = x -> y
b = x
a = y
将第二个和第三个方程式代入第一个方程式:
a = b -> a
问题是Haskell 没有类型来解决这个等式。特别是,不可能用有限数量的符号写下解决方案!它首先扩展到
a = b -> b -> a
然后
a = b -> b -> b -> a
永远。因此无法选择类型变量的类型以使它们匹配,GHC会大声抱怨。
答案 1 :(得分:3)
一般情况下,你不能做你想要做的事情,因为类型系统区分具有不同数量的参数的函数。实际上,您要做的是将值列表转换为函数的参数列表,这在上下文中没有意义。
但是,您指向的实例实际上只是foldl (*)
。如果您对函数中的所有变量执行相同的操作,则可以使用此功能(嗯,您应该使用foldl'
或foldr
,但你明白了。)