我最近写的
do
e <- (Left <$> m) <|> (Right <$> n)
more actions
case e of
Left x -> ...
Right y -> ...
Run Code Online (Sandbox Code Playgroud)
这看起来很尴尬。我知道protolude(和其他一些包)定义
-- Called eitherP in parser combinator libraries
eitherA :: Alternative f => f a -> f b -> f (Either a b)
Run Code Online (Sandbox Code Playgroud)
但即便如此,这一切还是感觉有点手动。有没有一些我没见过的漂亮模式可以收紧它?
现在有几次,我发现自己定义了:
(<?>) :: [a] -> [a] -> [a]
[] <?> ys = ys
xs <?> _ = xs
Run Code Online (Sandbox Code Playgroud)
当然,这是一个关联操作,空列表[]既是左标识又是右标识。它的功能类似于 Python 的or.
在我看来,这会是一个很好的(<|>),比原来更好的(++)。选择第一个非空列表感觉更像是我对命名类型类的期望,Alternative而不是连接列表。诚然,它不太合适MonadPlus,但我认为为救赎付出的代价很小。我们已经在标准库中拥有(++)和;(<>)我们是否需要另一个同义词,或者一个新函数(据我所知)会更有帮助吗?
我起初认为这可能是一个很好的Alternative例子,但在相关问题的答案ZipList之后的讨论让我相信了事实并非如此。除了向后兼容性和保持明智之外,当前实例而不是这个新实例还有什么理由呢?MonadPlus
我有一个list type 的输入[Maybe SomeType]和一个ptype 的谓词SomeType -> Bool,我想回答这个问题“谓词是否适用于输入中恰好出现的p所有s?” SomeType。
第一部分很简单:(map . fmap) p list类型为[Maybe Bool]。
一个重要的信息是我知道这一点length list >= 1并且all isNothing list == False两者都成立,因此必须至少有一个Just Truein (map . fmap) p list。
Bool但我如何从该列表中取出一首单曲呢?
我认为我可以利用折叠(例如 via foldl)和Maybe的MonadPlus实例,执行如下操作:
allTrueOrNothing :: [Maybe Bool] -> Bool
allTrueOrNothing = fromJust . foldl mplus mzero
Run Code Online (Sandbox Code Playgroud)
但这并不完全正确,因为无论它是什么,mplus都会返回左操作数,因此即使其输入是 也会返回。Just somethingsomething …