我的递归列表构造有什么问题?
我已经简化了相关功能。我在 monad 内构建列表时遇到问题。我怀疑存在优先级问题。
newtype Boundary = MkBoundary Integer
testFunc :: [Boundary] -> [Maybe Integer]
testFunc (MkBoundary x:xs)
| (even x) = Just x : testFunc xs
| otherwise = Nothing : testFunc xs
testFunc _ = []
这按预期工作。但我需要在一个单子中工作。在这个例子中我将使用 IO
testFunc :: [Boundary] -> IO [Maybe Integer]
testFunc (MkBoundary x:xs)
| (even x) = return $ Just x : testFunc xs
| otherwise = return $ Nothing : testFunc xs
testFunc _ = []
无论我如何尝试操纵优先级,这都会中断。
test.hs:6:35:
Couldn't match expected type `[Maybe Integer]'
with actual type `IO [Maybe Integer]'
In the return type of a call of `testFunc'
In the second argument of `(:)', namely `testFunc xs'
In the second argument of `($)', namely `Just x : testFunc xs'
Failed, modules loaded: none.
我想要完成的是构建一个列表,然后将其返回给 IO。我做错了什么?
I've simplified the functions in question. I'm having trouble constructing a list inside a monad. I suspect a precedence problem.
newtype Boundary = MkBoundary Integer
testFunc :: [Boundary] -> [Maybe Integer]
testFunc (MkBoundary x:xs)
| (even x) = Just x : testFunc xs
| otherwise = Nothing : testFunc xs
testFunc _ = []
This works as expected. But I need to work in a monad. I'll use IO for this example
testFunc :: [Boundary] -> IO [Maybe Integer]
testFunc (MkBoundary x:xs)
| (even x) = return $ Just x : testFunc xs
| otherwise = return $ Nothing : testFunc xs
testFunc _ = []
No matter how I try to manipulate precedence, this breaks.
test.hs:6:35:
Couldn't match expected type `[Maybe Integer]'
with actual type `IO [Maybe Integer]'
In the return type of a call of `testFunc'
In the second argument of `(:)', namely `testFunc xs'
In the second argument of `($)', namely `Just x : testFunc xs'
Failed, modules loaded: none.
What I am trying to accomplish is a constructing a list, then returning it to IO. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
luqui 回答了你的问题,我会注意到一个有用的组合器。
如果要对列表的所有元素执行单子操作,请使用“mapM”。它被定义为:
或等效的东西。 [如果您知道其他一些组合器,可以使用
liftM2
和foldr
编写mapM
。]在 GHCi 中测试:
luqui answered your question, I will note a useful combinator.
If you want to perform a monadic action for all elements of a list, use "mapM". It is defined as:
or something equivalent. [If you know some other combinators, you can write
mapM
withliftM2
andfoldr
.]test in GHCi:
问题是
testFunc xs
返回一个IO [Maybe Integer]
,并且您将它用作列表的尾部,就好像它是一个[Maybe Integer] ]
。您需要提取:或者,用更简洁的方式表达同一件事:
(
(<$>)
来自Control.Applicative
并具有专门针对 < code>IO 。它将函数应用于一元计算“内部”的值。)
哦,还有missingno所说的:-)
The problem is that
testFunc xs
returns anIO [Maybe Integer]
, and you are using it as the tail of a list as if it were a[Maybe Integer]
. You need to extract:Or, a more succinct way of saying the same thing:
(
(<$>)
is fromControl.Applicative
and has typespecialized to
IO
. It applies a function to the value "inside" a monadic computation.)Oh, also what missingno said :-)
您忘记更改第二种情况
另外,我认为您的示例函数可以写得更清楚,因为
这使纯代码与讨厌的 monad 东西分开。它还可以让您不必输入三次“return”! :)
最后,你为什么要创建这样一个函数? monad 部分(至少在您的示例中)似乎与主函数逻辑有些无关(因为您只是执行
return
)。也许您使用一些不错的库函数来保持您的函数纯净且不受影响?
You forgot to change the second case
Also, I think your example function could be more clearly written as
This keeps the pure code separated from the nasty monad stuff. It also saves you from having to type "return" thrice! :)
And finally, why are you creating such a function in the first place? The monad part (at least in your example) seems to be somewhat unrelated to the main function logic (since you are just doing a
return
).Perhaps you use some nice library functions to keep your function pure and untouched?