我正在寻找像
这样的东西xvalue,yvalue
30,20
50,30
70,10
Haskell中是否有这样的功能?
答案 0 :(得分:7)
不是现成的解决方案,但使用guard
(来自Control.Monad
)和(<$)
(来自Data.Functor
)我们可以写:
ensure :: Alternative f => (a -> Bool) -> a -> f a
ensure p a = a <$ guard (p a)
(感谢Daniel Wagner建议这个功能的好名字。)
可疑口味的更多无点拼写是\p -> (<$) <*> guard . p
。
答案 1 :(得分:5)
使用Control.Monad
:
liftPredM :: MonadPlus m => (a -> Bool) -> a -> m a
liftPredM p = mfilter p . return
另一种方法是使用Data.Foldable
:
liftPredF :: (a -> Bool) -> a -> Maybe a
liftPredF f = find f . pure
然而,这不太通用,所以我倾向于支持基于MonadPlus
的实施。
但在这两种情况下,我们的想法是首先解除一个“裸体”的问题。使用pure
或return
将值放入容器中,然后应用过滤器。通常,您不需要为此声明实际功能;相反,你可以在你需要的地方内联组合。
示例:
Prelude Control.Monad> liftPredMaybe even 42 :: Maybe Integer
Just 42
Prelude Control.Monad> liftPredMaybe (even . length) "foo" :: Maybe String
Nothing
Prelude Control.Monad> liftPredMaybe (odd . length) "foo" :: Maybe String
Just "foo"