[英]Haskell Monad.Writer
I am writing a logger for a sorting function like this:我正在为这样的排序功能编写一个记录器:
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]
but i get this error:但我收到此错误:
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.
I have read this error message word for word but I am not any closer to what the problem is?我已经逐字逐句地阅读了这条错误消息,但我还没有更接近问题所在? I tried compiling with out the deceleration, for a fresh set of errors like this:
我尝试在不减速的情况下进行编译,但出现了一组新的错误,如下所示:
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.
A nod in the right direction: 向正确的方向点头:
y
? y
的类型是什么? bubble(x:ys)
? bubble(x:ys)
的类型是什么? (:)
? (:)
是什么类型? Answers: 答案:
(In these answers, a
is the same a
as in bubble :: (Ord a) => [a] -> Writer [String] [a]
.) (在这些答案,
a
是同a
作为bubble :: (Ord a) => [a] -> Writer [String] [a]
y :: a
bubble(x:ys) :: Writer [String] [a]
bubble
is a function, bubble(x:ys)
is the result of applying bubble
to x:ys
bubble
是一个函数, bubble(x:ys)
是对x:ys
应用bubble
的结果 (:) :: b -> [b] -> [b]
:
is an operator; :
是运算符; whatever type its first operand has, its second operand must have the type "list of whatever type the first operand has", and the result has that same list type. Given that you have given y
and bubble(x:ys)
as the operands to :
, can you see now what the problem is? 既然你已经给
y
和bubble(x:ys)
作为操作数来:
,你能看到现在的问题是什么?
It's somewhat unfortunate, in cases like these, that Writer wa
is a type synonym for WriterT w Identity a
. 在这种情况下,
Writer wa
是WriterT w Identity a
的类型同义词是有些不幸WriterT w Identity a
。 It makes the compiler error messages (which are normally very informative) much harder to interpret. 这使编译器错误消息(通常非常有用)更加难以解释。 So my suggestion here is to simply ignore the content of the error message entirely and pretend you're the type checker.
因此,我的建议是完全忽略错误消息的内容,并假装您是类型检查器。
@dave4420 provided a very good hint, I think. 我认为@ dave4420提供了很好的提示。 I'll add to that by saying: don't remove the type declaration for
bubble
- instead, go the opposite way: break bubble
down into smaller helper functions, providing type declarations for each one. 我要说的是:不要删除
bubble
的类型声明-相反,请按照相反的方式:将bubble
分解为较小的辅助函数,为每个函数提供类型声明。 Then it should become much more clear where your problem lies. 然后应该更加清楚您的问题所在。
My only other hint is that this is a common issue with writing monadic code: remembering which values are of monadic type, which aren't, and when to "lift." 我唯一的另一个暗示是,这是编写单子代码的常见问题:记住哪些值属于单子类型,哪些不是,何时“提升”。
The message讯息
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)
无法将预期类型“WriterT [String] Data.Functor.Identity.Identity [a]”与实际类型“[a0]”匹配在“do”块的 stmt 中:y: bubble (x: ys)
Is referring to the fact that y:bubble(x:ys)
has a type of [a]
and bubble
's is supposed to be a Writer [String] [a]
.指的是
y:bubble(x:ys)
的类型是[a]
而bubble
的应该是Writer [String] [a]
。 Ie the types do not match .即类型不匹配。
y:bubble(x:ys)
is just a list, but what you need it to be is a list embedded within your writer monad. y:bubble(x:ys)
只是一个列表,但您需要的是嵌入在您的 writer monad 中的列表。 In order to embed it as the result of your writer monad you need to use return
.为了将它作为你的 writer monad 的结果嵌入,你需要使用
return
。
y:bubble(x:ys)
has a type of [a]
y:bubble(x:ys)
的类型是[a]
return $ y:bubble(x:ys)
has a type of Writer [String] [a]
return $ y:bubble(x:ys)
的类型为Writer [String] [a]
The same applies to x:bubble(y:ys)
.这同样适用于
x:bubble(y:ys)
。 Thus your code ought to be:因此你的代码应该是:
bubble :: (Ord a) => [a] -> Writer [String] [a]
bubble (x:y:ys)
| x > y = do
tell [show x ++ " why does this not work"]
return $ y:bubble(x:ys)
| otherwise = do
tell [show y ++ " is a number"]
return $ x:bubble(y:ys)
bubble [x] = do
tell ["nothing works"]
return [x]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.