我正在寻找一个基本上类似于mapM
列表的函数——它执行一系列单子操作,将列表中的每个值作为参数——并且每个单子函数都返回m (Maybe b)
。但是,我希望它在导致函数返回Just
值的第一个参数之后停止,之后不再执行,并返回该值。
好吧,只显示类型签名可能会更容易:
findM :: (Monad m) => (a -> m (Maybe b)) -> [a] -> m (Maybe b)
其中 b 是第一个Just
值。结果Maybe
中的 in 来自ing(如果是空列表等),与Monadic 函数find
的返回无关。Maybe
我似乎无法通过直接应用库函数来实现这一点。我可以使用
findM f xs = fmap (fmap fromJust . find isJust) $ mapM f xs
这会起作用,但我对此进行了测试,似乎所有的单子动作都是在 call 之前执行的find
,所以我不能在这里依赖懒惰。
ghci> findM (\x -> print x >> return (Just x)) [1,2,3]
1
2
3
-- returning IO (Just 1)
实现这个函数的最佳方法是什么,在第一次“刚刚”返回后不会执行单子动作?会做的事情:
ghci> findM (\x -> print x >> return (Just x)) [1,2,3]
1
-- returning IO (Just 1)
甚至,理想情况下,
ghci> findM (\x -> print x >> return (Just x)) [1..]
1
-- returning IO (Just 1)
希望有一个不使用显式递归的答案,如果可能的话,是库函数的组合吗?或者甚至是免费的?