簡體   English   中英

Haskell樹-搜索樹

[英]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推斷的類型)。

然后,您應該查找(++)的類型簽名以查看可能是什么問題(例如,使用hooglehayooghci )在您的情況下,問題在於(++)的第一個和第二個參數的類型(++)不一樣,但應該一樣。

想想你在做什么。 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的結果是:

  1. 一個空列表或一個非空列表(分別為FalseTrue )。 因此hasValue
  2. 僅重復x值的列表,在這種情況下,長度很重要。 因此是numValue

     findValue :: a -> MyTree a -> [a] findValue xt = replicate (numValue xt) x 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM