2012-06-26 225 views
1

我寫這樣的排序功能的記錄:哈斯克爾Monad.Writer

bubble :: (Ord a) => [a] -> Writer [String] [a] 
bubble (x:y:ys) 
     | x > y = do 
       tell [show x ++ " why does this not work"] 
       y:bubble(x:ys) 
     | otherwise = do 
       tell [show y ++ " is a number"] 
       x:bubble(y:ys) 
bubble [x] = do 
      tell ["nothing works"] 
      return [x] 

,但我得到這個錯誤:

Couldn't match expected type `WriterT 
            [String] Data.Functor.Identity.Identity [a]' 
       with actual type `[a0]' 
    In a stmt of a 'do' block: y : bubble (x : ys) 
    In the expression: 
     do { tell [show x ++ " why does this not work"]; 
      y : bubble (x : ys) } 
    In an equation for `bubble': 
     bubble (x : y : ys) 
      | x > y 
      = do { tell [show x ++ " why does this not work"]; 
       y : bubble (x : ys) } 
      | otherwise 
      = do { tell [show y ++ " is a number"]; 
       x : bubble (y : ys) } 
Failed, modules loaded: none. 

我看了一個字,但我這個錯誤消息字我沒有接近問題所在嗎? 我試圖編譯出來的減速,對一組新的錯誤是這樣的:

q.hs:21:17: 
    No instance for (MonadWriter [[Char]] []) 
     arising from a use of `tell' 
    Possible fix: 
     add an instance declaration for (MonadWriter [[Char]] []) 
    In a stmt of a 'do' block: 
     tell [show x ++ " why does this not work"] 
    In the expression: 
     do { tell [show x ++ " why does this not work"]; 
      y : bubble (x : ys) } 
    In an equation for `bubble': 
     bubble (x : y : ys) 
      | x > y 
      = do { tell [show x ++ " why does this not work"]; 
       y : bubble (x : ys) } 
      | otherwise 
      = do { tell [show y ++ " is a number"]; 
       x : bubble (y : ys) } 
Failed, modules loaded: none. 

回答

3

在正確的方向點頭:

  1. 什麼是y類型?
  2. bubble(x:ys)是什麼類型的?
  3. (:)是什麼類型的?

數目:

(在這些答案,a相同abubble :: (Ord a) => [a] -> Writer [String] [a]。)

  1. y :: a
  2. bubble(x:ys) :: Writer [String] [a]
    • bubble是一個函數,bubble(x:ys)是施加到bubblex:ys
  3. (:) :: b -> [b] -> [b]
    • :是一個操作符的結果;無論第一個操作數具有哪種類型,其第二個操作數必須具有「第一個操作數具有的任何類型的列表」類型,並且結果具有相同的列表類型。

既然你已經給ybubble(x:ys)作爲操作數:,可現在的問題是什麼,你看到了什麼?

+0

hmm是1. Ord a 2.使用列表調用的函數3.將元素添加到列表的操作數?是否需要更改我的聲明 –

+1

不,您的聲明看起來不錯。更多:) – mergeconflict

+0

@baronaron你的類型聲明很好,問題出現在'y:bubble(x:ys)'這一行中。請參閱我的編輯。 – dave4420

3

在這種情況下,Writer w aWriterT w Identity a的同義詞,這有點不幸。它使編譯器的錯誤信息(通常非常有用)很難解釋。所以我的建議是簡單地完全忽略錯誤信息的內容並假裝你是類型檢查器。

@dave4420提供了一個非常好的提示,我想。我會補充說:不要刪除類型聲明bubble - 而是,相反的方式:打破bubble下變成較小的幫助函數,爲每一個提供類型聲明。那麼它應該變得更清楚你的問題在哪裏。

我唯一的提示是,這是一個寫monadic代碼的常見問題:記住哪些值是monadic類型,哪些值不是,什麼時候「提升」。「