Haskell 哈斯克尔·蒙纳德,作家

Haskell 哈斯克尔·蒙纳德,作家,haskell,Haskell,我正在为排序函数编写一个记录器,如下所示: 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 t

我正在为排序函数编写一个记录器,如下所示:

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] 
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.
但我得到了这个错误:

 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.
我逐字逐句地读了这个错误消息,但我不知道问题出在哪里? 我尝试在没有减速的情况下编译,以获得一组新的错误,如:

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

朝正确方向点头:

什么是y型? 泡泡的类型是什么? 什么类型的:? 答复:

在这些答案中,a与bubble::Ord a=>[a]->Writer[String][a]中的a相同

y::a bubblex:ys::Writer[String][a] bubble是一个函数,bubblex:ys是将bubble应用于x:ys的结果 ::b->[b]->[b] :是操作员;无论第一个操作数具有何种类型,其第二个操作数的类型列表必须与第一个操作数的类型列表相同,并且结果具有相同的列表类型。
考虑到您已将y和bubblex:ys作为操作数指定给:,您现在能看到问题所在吗?

正确方向的点头:

什么是y型? 泡泡的类型是什么? 什么类型的:? 答复:

在这些答案中,a与bubble::Ord a=>[a]->Writer[String][a]中的a相同

y::a bubblex:ys::Writer[String][a] bubble是一个函数,bubblex:ys是将bubble应用于x:ys的结果 ::b->[b]->[b] :是操作员;无论第一个操作数具有何种类型,其第二个操作数的类型列表必须与第一个操作数的类型列表相同,并且结果具有相同的列表类型。
鉴于您已经将y和bubblex:ys作为操作数指定给:,您现在能看到问题所在吗?

在类似的情况下,Writer w a是Writer w Identity a的类型同义词,这有点不幸。这使得编译器错误消息(通常信息量很大)更难解释。因此,我的建议是完全忽略错误消息的内容,并假装您是类型检查器

@我认为,dave4420提供了一个非常好的提示。我将补充说:不要删除bubble的类型声明,相反,将bubble分解为更小的帮助函数,为每个函数提供类型声明。那么,你的问题所在就应该更加清楚了


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

在这种情况下,Writer w a是Writer w Identity a的类型同义词,这有点不幸。这使得编译器错误消息(通常信息量很大)更难解释。因此,我的建议是完全忽略错误消息的内容,并假装您是类型检查器

@我认为,dave4420提供了一个非常好的提示。我将补充说:不要删除bubble的类型声明,相反,将bubble分解为更小的帮助函数,为每个函数提供类型声明。那么,你的问题所在就应该更加清楚了


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

hmm为1。作战需求文件a 2。使用列表3调用的函数。要将元素添加到列表中的操作数?我需要更改声明吗?@baronaron您的类型声明很好,问题在y:bubblex:ys行。看我的编辑。非常感谢你们。Stack Overflow社区再次伸出援手:再次感谢你们。嗯,是1。作战需求文件a 2。使用列表3调用的函数。要将元素添加到列表中的操作数?我需要更改声明吗?@baronaron您的类型声明很好,问题在y:bubblex:ys行。看我的编辑。非常感谢你们。Stack Overflow社区再次伸出援手:再次感谢你们两位。