我之前从未在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)'
谢谢大家。
答案 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)