2017-10-17 98 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) 
相關問題