为什么无点样式不会引起问题?

时间:2019-02-19 07:29:09

标签: haskell

我从https://www.haskell.org/tutorial/pitfalls.html页上了解了“同构限制”,但不明白最后一点:

  

定义的函数通常会违反该限制   以更高阶的方式定义,例如   标准前奏:

     

sum = foldl (+) 0

     

按原样,这将导致静态类型错误。我们可以通过解决问题   添加类型签名:

     

sum :: (Num a) => [a] -> a

     

还请注意,如果我们编写以下内容,则不会出现此问题:

     

sum xs = foldl (+) 0 xs

     

因为该限制仅适用于模式绑定。

为什么最后一点不会引起任何错误?

1 个答案:

答案 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不适用于功能绑定。