list - 我的递归列表构造有什么问题?

标签 list haskell monads

我已经简化了相关功能。我在单子(monad)中构建列表时遇到问题。我怀疑有优先级问题。

newtype Boundary = MkBoundary Integer

testFunc :: [Boundary] -> [Maybe Integer]
testFunc (MkBoundary x:xs)
   | (even x) = Just x : testFunc xs
   | otherwise = Nothing : testFunc xs
testFunc _ = []

这按预期工作。但我需要在单子(monad)中工作。我将在此示例中使用 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。我做错了什么?

最佳答案

luqui 回答了你的问题,我会记下一个有用的组合子。

如果您想对列表的所有元素执行一元操作,请使用“mapM”。定义为:

 mapM f [] = return []
 mapM f (x:xs) = do y <- f x
                    ys <- mapM f xs
                    return (y:ys)

或类似的东西。 [如果你知道一些其他的组合器,你可以用 liftM2foldr 编写 mapM。]

 testFunc = mapM f
     where f (MkBoundary x) | even x = do print x
                                          return $ Just x
                            | otherwise = return Nothing

在 GHCi 中测试:

*Main> testFunc [MkBoundary 2, MkBoundary 3, MkBoundary 4]
2
4
[Just 2,Nothing,Just 4]

关于list - 我的递归列表构造有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8190305/

相关文章:

javascript - 通过javascript获取点击时列表项的内部值

c++ - std::list<std::shared_ptr>::erase 得到一个 SIGSEGV

haskell - Haskell 中的一元 IO 构造只是一种约定吗?

haskell - 如何处理多级缩进?

haskell - 找不到类似liftM2的功能

scala - 作家单子(monad)实际上与状态单子(monad)相同吗?

java - 在 Java 中读取一个文本文件直到一个空行

haskell - 避免多次列表遍历的好处

haskell - 具有多个相同变压器的 monad 堆栈

arrays - lisp 减少堆(数组与列表)