1

我正在为这样的排序功能编写一个记录器:

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.
4

2 回答 2

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)是应用bubble到的结果x:ys
  3. (:) :: b -> [b] -> [b]
    • :是运算符;无论其第一个操作数具有何种类型,其第二个操作数必须具有“第一个操作数具有的任何类型的列表”类型,并且结果具有相同的列表类型。

鉴于您已将ybubble(x:ys)作为 的操作数:,您现在能看出问题所在了吗?

于 2012-06-26T23:55:09.100 回答
3

有点不幸的是,在这种情况下,这Writer w aWriterT w Identity a. 它使编译器错误消息(通常信息量很大)更难解释。所以我在这里的建议是完全忽略错误消息的内容,假装你是类型检查器。

我认为@dave4420 提供了一个很好的提示。我将补充说:不要删除 - 的类型声明,bubble相反,采取相反的方式:分解bubble成更小的辅助函数,为每个函数提供类型声明。然后它应该变得更加清楚你的问题出在哪里。

我唯一的另一个提示是,这是编写 monadic 代码的一个常见问题:记住哪些值是 monadic 类型,哪些不是,以及何时“提升”。

于 2012-06-27T00:11:25.727 回答