Oru*_*rup 6 haskell types type-inference
我的功能如下:
foo :: Int -> a -> [a]
foo n v = bar n
where
bar :: Int -> [a]
bar n = take n $ repeat v
Run Code Online (Sandbox Code Playgroud)
使用ghci报告此错误:
Couldn't match type `a' with `a1'
`a' is a rigid type variable bound by
the type signature for foo :: Int -> a -> [a] at hs99.hs:872:1
`a1' is a rigid type variable bound by
the type signature for bar :: Int -> [a1] at hs99.hs:875:9
Expected type: [a1]
Actual type: [a]
In the expression: take n $ repeat v
In an equation for `bar': bar n = take n $ repeat v
Run Code Online (Sandbox Code Playgroud)
如果删除bar的类型声明,则可以编译代码而不会出错.那么这里吧的正确类型声明是什么?并且为什么会发生错误,因为bar的类型声明比bar的定义更通用(在foo中绑定到某种类型)?
谢谢你的帮助!
将a在
foo :: Int -> a -> [a]
Run Code Online (Sandbox Code Playgroud)
和ain
bar :: Int -> [a]
Run Code Online (Sandbox Code Playgroud)
是具有相同名称的不同类型变量.
要获得您期望的行为,请打开ScopedTypeVariables扩展(例如,通过插入{-# LANGUAGE ScopedTypeVariables #-}源文件的顶部),并将类型签名更改foo为
foo :: forall a. Int -> a -> [a]
Run Code Online (Sandbox Code Playgroud)
如果未启用ScopedTypeVariables,就好像您的原始代码是这样编写的:
foo :: forall a. Int -> a -> [a]
foo n v = bar n
where
bar :: forall a. Int -> [a]
bar n = take n $ repeat v
Run Code Online (Sandbox Code Playgroud)
如果省略类型注释,那么ghci隐式使用ScopedTypeVariables是不正确的bar.
相反,你给出的bar与ghci类型冲突的类型注释- 你断言bar有一个ghci知道它不能拥有的类型.
删除类型注释时,将删除冲突.
ScopedTypeVariables更改您提供的类型注释的含义.它不会影响ghc如何推断类型.