我从https://www.haskell.org/tutorial/pitfalls.html页上了解了“同构限制”,但不明白最后一点:
定义的函数通常会违反该限制 以更高阶的方式定义,例如 标准前奏:
sum = foldl (+) 0
按原样,这将导致静态类型错误。我们可以通过解决问题 添加类型签名:
sum :: (Num a) => [a] -> a
还请注意,如果我们编写以下内容,则不会出现此问题:
sum xs = foldl (+) 0 xs
因为该限制仅适用于模式绑定。
为什么最后一点不会引起任何错误?
答案 0 :(得分:2)
因为该限制仅适用于模式绑定。
本质上,当我们使用形式的函数绑定定义函数时,MR不适用
f arg1 ... argN = ...
带有N > 0
。
直觉如下。 MR的目的是避免意外将Haskell非功能转换为较低级别的功能。例如,
x = 3 + 4
不是功能。但是,其类型为Num a => a
,通常将其实现为从Num
字典到3+4
的结果的函数,其中+
是字典定义的函数。这可能会导致性能下降,因为每次使用x
时,都需要从头开始重新计算总和。例如,如果我们要计算print (x :: Int) >> print (x :: Double)
,这是不可避免的。但是实际上在不同类型上使用x
并不常见。
因此,MR使x
是单态的,从而使我们不能在单一类型上使用它。这样可以避免重新计算。
但是,如果x
已经是 一个函数,则保持该多态性没有任何危害,因为无论如何我们都是在“重新计算”函数调用。因此,MR不适用于功能绑定。