Pet*_*rko 26 haskell type-inference monomorphism-restriction
Haskell中的类型推断有一点学习曲线(至少可以说!).开始学习它的一个好方法是使用简单的例子.因此,以下是类型推断的"hello world".
请考虑以下示例:
Prelude> :t 3
3 :: (Num t) => t
Prelude> let x = 3
Prelude> :t x
x :: Integer
Run Code Online (Sandbox Code Playgroud)
问题是:为什么3和x有不同的类型?
链接摘要:
阅读以下答案的完整故事; 这里只是一个链接摘要:
pig*_*ker 32
这里有另一个因素,在acfoltzer包含的一些链接中提到过,但在这里可能值得明确.你遇到了单态限制的影响.当你说
let x = 5
Run Code Online (Sandbox Code Playgroud)
你做一个变量的顶级定义.MR坚持认为,这些定义在没有类型签名的情况下,应该通过为未解析的类型变量选择(希望)合适的默认实例来专用于单形值.相反,当您使用要求推断类型时,不会施加此类限制或违约.所以:t
> :t 3
3 :: (Num t) => t
Run Code Online (Sandbox Code Playgroud)
因为3确实超载了:它被任何数字类型所接受.默认规则选择Integer默认数字类型,因此
> let x = 3
> :t x
x :: Integer
Run Code Online (Sandbox Code Playgroud)
但现在让我们关掉MR.
> :set -XNoMonomorphismRestriction
> let y = 3
> :t y
y :: (Num t) => t
Run Code Online (Sandbox Code Playgroud)
没有MR,定义就像它可以是多态的一样,就像重载一样3.只是检查...
> :t y * (2.5 :: Float)
y * (2.5 :: Float) :: Float
> :t y * (3 :: Int)
y * (3 :: Int) :: Int
Run Code Online (Sandbox Code Playgroud)
请注意y = 3,根据fromInteger相关Num实例提供的方法,多态在这些用途中具有不同的专业性.也就是说,y不与特定表示相关联3,而是与构建表示的方案相关联3.天真的编译,这是一个缓慢的配方,有些人认为这是MR的动机.
我(当地假装)在关于单态限制是否是一个更小或更大的邪恶的辩论中保持中立.我总是为顶级定义编写类型签名,因此对于我想要实现的内容没有任何歧义,并且MR不是重点.
在尝试学习类型系统如何工作时,将类型推断的各个方面分开是非常有用的
"遵循计划",将多态定义专门用于特定用例:一个相当强大的约束求解问题,需要通过反向链接进行基本统一和实例解析; 和
"猜测计划",推广类型以将多态类型方案分配给没有类型签名的定义:这非常脆弱,你越过基本的Hindley-Milner规则,类型类,具有更高级别的多态性, GADTs,陌生人的事情变成了.
很好地了解第一个如何工作,并理解为什么第二个是困难的.类型推断的许多奇怪之处与第二种相关,并且具有启发性,例如单态性限制试图在模糊性面前提供有用的默认行为.
| 归档时间: |
|
| 查看次数: |
958 次 |
| 最近记录: |