无法将预期类型“[Char]”与实际类型“a”匹配

时间:2017-10-17 17:04:25

标签: haskell printing tree

我之前从未在Stackoverflow中看到过这个具体问题,其他问题对我没有帮助(我在打开此问题之前尝试过)。

当我尝试以这种方式打印二进制树时:

data BinTree a = ET | Branch (BinTree a) a (BinTree a) deriving Show

ejC:: BinTree a -> String
ejC ET = ""
ejC (Branch x y z) = (ejC x) ++ "|-" ++ y ++ "-|" ++ (ejC z)

模块出现此错误:

Couldn't match expected type `[Char]' with actual type `a'
`a' is a rigid type variable bound by
the type signature for ejC :: BinTree a -> String at Types2.hs:24:7
Relevant bindings include
z :: BinTree a (bound at Types2.hs:26:17)
y :: a (bound at Types2.hs:26:15)
x :: BinTree a (bound at Types2.hs:26:13)
ejC :: BinTree a -> String (bound at Types2.hs:25:1)
In the first argument of `(++)', namely `y'
In the second argument of `(++)', namely `y ++ "-|" ++ (ejC z)'

谢谢大家。

1 个答案:

答案 0 :(得分:5)

GHC在这里告诉你很多。它似乎在说y,对吧?关于(++)?那么,那些东西的类型是什么?

y :: a
(++) :: [t] -> [t] -> [t]

好吧,由于y(++)的参数,因此a[t]的类型相同。因为("-|" ++ (ejC z)),一个String,是(++)的另一个参数,该类型必须是String:

a ~ [t] ~ String

但是你的类型签名表明它适用于任何类型a,而不仅仅是String。因此错误。

你可以通过几种方式解决这个问题。您可以更改类型签名以将a限制为String:

ejC:: BinTree String -> String
ejC = -- ...

它不适用于任何类型的树,只是字符串树,但也许这就是你想要的。

或者,您可以尝试以某种方式将树中的a值转换为字符串。有一种常见的方法可以将一个东西变成一个String,这是通过使用show函数,但它要求该类型具有Show的实例。因此,将该约束添加到函数签名中,并在函数体中调用show

ejC:: Show a => BinTree a -> String
ejC ET = ""
ejC (Branch x y z) = (ejC x) ++ "|-" ++ show y ++ "-|" ++ (ejC z)