ban*_*ana 1 haskell functional-programming dot-operator
在下面的Haskell代码中,函数typeError没有进行类型检查.
wrap x = [x]
listf :: [[a]] -> [[a]]
listf = id
typeCheck :: [a] -> [[a]]
typeCheck x = listf (wrap x)
typeError :: [a] -> [[a]]
typeError = wrap . listf
Run Code Online (Sandbox Code Playgroud)
如果GHC取消注释,GHC会产生此错误:
Couldn't match type `a' with `[a0]'
`a' is a rigid type variable bound by
the type signature for typeError :: [a] -> [[a]] at tim.hs:10:1
Expected type: [a] -> [a]
Actual type: [[a0]] -> [[a0]]
In the second argument of `(.)', namely `listf'
In the expression: wrap . listf
Run Code Online (Sandbox Code Playgroud)
我不明白为什么.a应该能够统一[a0]- 它们是独立的类型变量.这正是它所推断的类型typeCheck- 但不是在使用.运算符时.
Hugs会产生一个非常相似且类似的虚假错误消息:
ERROR "repro.hs":10 - Inferred type is not general enough
*** Expression : typeError
*** Expected type : [a] -> [[a]]
*** Inferred type : [[a]] -> [[[a]]]
Run Code Online (Sandbox Code Playgroud)
此外,这工作正常:
listf' :: [a] -> [a]
listf' = id
typeCheck' :: [a] -> [[a]]
typeCheck' = wrap . listf'
Run Code Online (Sandbox Code Playgroud)
只有[[a]]或[[[a]]]或更大时才会出现此问题.这是什么交易?
你似乎已经扭转了这里的功能构成.
-- This
typeCheck :: [a] -> [[a]]
typeCheck x = listf (wrap x)
-- is the same as
typeCheck' :: [a] -> [[a]]
typeCheck' = listf . wrap
-- while this
typeError :: [a] -> [[a]]
typeError = wrap . listf
-- is the same as
typeError' :: [a] -> [[a]]
typeError' x = wrap (listf x)
Run Code Online (Sandbox Code Playgroud)
现在应该明白为什么这不起作用.listf要求它的论点是[[a]],但typeError声称它适用于任何声明[a].