为什么这个函数需要[[a]]?

Kat*_*Kim 0 haskell type-systems type-inference

我正在编写Haskell代码练习尾递归来反转列表并提出了这个解决方案:

reverseh' [] list = list
reverseh' (x:xs) list = reverseh' (xs) (x ++ list)
reverse' x = reverseh' x []
Run Code Online (Sandbox Code Playgroud)

它只适用于列表列表,但我希望它具有类型签名[a] -> [a].

你能解释我在这里做错了什么吗?

Rüd*_*nke 9

如果没有得到预期的类型,最好添加一个显式类型签名来告诉编译器你想要的类型,这里:

reverseh' :: [a] -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

然后你得到一个编译错误:

Couldn't match expected type `[a]' with actual type `a'     
  `a' is a rigid type variable bound by                     
      the type signature for reverseh' :: [a] -> [a] -> [a] 
      at reverseh.hs:1:14                                   
Relevant bindings include                                   
  list :: [a] (bound at reverseh.hs:3:18)                   
  xs :: [a] (bound at reverseh.hs:3:14)                     
  x :: a (bound at reverseh.hs:3:12)                        
  reverseh' :: [a] -> [a] -> [a] (bound at reverseh.hs:2:1) 
In the first argument of `(++)', namely `x'                 
In the second argument of reverseh', namely `(x ++ list)'   
Run Code Online (Sandbox Code Playgroud)

这告诉你in (x ++ list),x需要是类型[a]才能进行类型检查,但是考虑到类型签名,x实际上是类型a.所以你想++用类型的函数替换a -> [a] -> [a],所以你去(x : list).