[英]Haskell Tree - searching through tree
我的分配遇到問題:我正在嘗試編寫一個代碼,該代碼列出所有要告訴他的節點值(例如,將值4的所有節點都整理到一個整齊的列表中)。
我寫了以下內容:
findValue :: a -> (MyTree a) -> [a]
findValue x Leaf = []
findValue x (Node a l r)
|a == x = x++(findValue x l)++(findValue x r)
|a /= x = (findValue x l)++(findValue x r)
我對樹的定義如下:
data MyTree a = Leaf | Node a (MyTree a) (MyTree a)
我收到以下錯誤消息:
Couldn't match expected type ‘[a]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for findValue :: a -> MyTree a -> [a]
at assignment.hs:10:14
Relevant bindings include
r :: MyTree a (bound at assignment.hs:12:25)
l :: MyTree a (bound at assignment.hs:12:23)
a :: a (bound at assignment.hs:12:21)
x :: a (bound at assignment.hs:12:11)
findValue :: a -> MyTree a -> [a]
(bound at assignment.hs:11:1)
In the first argument of ‘(++)’, namely ‘x’
In the expression: x ++ (findValue x l) ++ (findValue x r)
如果有人向我解釋錯誤信息,我將非常高興。 提前致謝!
(++)
的類型為[a] -> [a] -> [a]
,但是x
的類型為a
。 這樣你就可以寫
x : (findValue xl) ++ (findValue xr)
(使用“ cons”運算符(:) :: a -> [a] -> [a]
x : (findValue xl) ++ (findValue xr)
(:) :: a -> [a] -> [a]
),或
[x] ++ (findValue x l) ++ (findValue x r)
這是您應該自己確定的方法:
該錯誤說明Couldn't match exptected type '[a]' with actual type 'a' ... in the first argument of '(++)', namely 'x'
這意味着(++)
的參數x
(在指定的行上) 應具有類型[a]
(這是預期的類型),但實際上具有類型a
( 推斷的類型)。
然后,您應該查找(++)
的類型簽名以查看可能是什么問題(例如,使用hoogle , hayoo或ghci )在您的情況下,問題在於(++)
的第一個和第二個參數的類型(++)
不一樣,但應該一樣。
想想你在做什么。 findValue
的類型a -> MyTree a -> [a]
,這意味着x
的類型為a
。
但是, (++)
運算符的類型為[a] -> [a] -> [a]
,但是您正在編寫x ++ (findValue xl) ++ (findValue xr)
。 因此,它給你一個錯誤,說:
Couldn't match expected type ‘[a]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for findValue :: a -> MyTree a -> [a]
at assignment.hs:10:14
Relevant bindings include
r :: MyTree a (bound at assignment.hs:12:25)
l :: MyTree a (bound at assignment.hs:12:23)
a :: a (bound at assignment.hs:12:21)
x :: a (bound at assignment.hs:12:11)
findValue :: a -> MyTree a -> [a]
(bound at assignment.hs:11:1)
In the first argument of ‘(++)’, namely ‘x’
In the expression: x ++ (findValue x l) ++ (findValue x r)
錯誤消息清楚地表明,它Couldn't match expected type '[a]' with actual type 'a'
。 它進一步告訴您問題出In the first argument of '(++)', namely 'x'
哪里, In the first argument of '(++)', namely 'x'
。 它甚至告訴您在哪里找到該表達式, In the expression: x ++ (findValue xl) ++ (findValue xr)
。
Haskell錯誤消息可能看起來很嚇人,但實際上它們非常有用,而且易於理解。 不要讓像'a' is a rigid type variable bound by
這樣'a' is a rigid type variable bound by
短語'a' is a rigid type variable bound by
嚇到你。
我知道當您閱讀的第二句話是您不理解的時候就很容易放棄,而且我知道在SO上發布有關此問題的問題會更容易。 幫自己一個忙,不要。 了解如何理解錯誤消息。
給一個人一條魚,他會吃一天。 教一個人釣魚,他將一生吃飽。
順便說一句,為什么需要findValue
a -> MyTree a -> [a]
類型的findValue
函數? 擁有:
hasValue :: a -> MyTree a -> Bool
hasValue x Leaf = False
hasValue x (Node a l r)
| a == x = True
| otherwise = findValue x l || findValue x r
numValue :: a -> MyTree a -> Int
numValue x Leaf = 0
numValue x (Node a l r)
| a == x = depth + 1
| otherwise = depth
where depth = findValue x l + findValue x r
對我來說,擁有findValue
函數沒有任何意義,因為給定findValue xt
的結果是:
False
或True
)。 因此hasValue
。 僅重復x
值的列表,在這種情況下,長度很重要。 因此是numValue
。
findValue :: a -> MyTree a -> [a] findValue xt = replicate (numValue xt) x
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.