2017-10-17 72 views
1

我从来没有在#1见过这个具体问题和其他问题没有帮助我(我以前试过开)。无法匹配预期的类型`[字符]“与实际类型'一”

当我尝试打印二叉树这种方式如下:

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)' 

谢谢大家。

+3

'(EJC X)++ “| - ” ++Ÿ++ “ - |” ++(ejC z)'应该是'(ejC x)++“| - ”++ show y ++“ - |” ++(ejC z)' – Alec

+0

您的解决方案工作。所以如此如此如此感谢。 –

回答

5

GHC在这里告诉你一个可怕的事情。它似乎在说一些关于y的东西,对吧?而关于(++)?那么,这些东西的类型是什么?

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

那么,既然y是一个参数,它(++)必须是a是相同类型[t]的情况。而且,由于("-|" ++ (ejC z)),一个字符串,是其他参数(++),该类型必须为String:

a ~ [t] ~ String 

但你的类型的签名说,它适用于任何类型的a可言,而不仅仅是字符串。因此错误。

你可以通过几种方法解决这个问题。你可以改变你的类型签名来限制a是字符串:

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

它不会对任何类型的树工作,只是字符串树,但也许这就是你想要的。

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

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