我有以下功能
type Assignment = [(Ref, Val)]
predi2 :: [(Val,Val)] -> Ref -> Ref -> (Maybe Assignment -> [Maybe Assignment])
predi2 f k1 k2 = \ma -> case ma of
Nothing -> [Nothing]
Just a -> case lookup k1 a of
Nothing -> [Nothing]
Just e1 -> case lookup k2 a of
Nothing -> [Nothing]
Just e2 -> if elem (e1, e2) f
then [Just a]
else []
考虑到Maybe的所有实例,我认为我可以将它简化为Maybe monad中更简单的内容:
predi2 :: [(Val,Val)] -> Ref -> Ref -> (Maybe Assignment -> [Maybe Assignment])
predi2 f k1 k2 = [\ma -> do
a <- ma
e1 <- lookup k1 a
e2 <- lookup k2 a
if elem (e1, e2) f then (return a) else ???]
但我的问题是最后的问题,我需要什么都不返回。
这是我的问题:是否有可能以[f a] = []的方式返回任何内容?
答案 0 :(得分:9)
不,不是。
我会更像这样写predi2
函数:
predi2 f k1 k2 ma = fromMaybe [Nothing] $ do
a <- ma
e1 <- lookup k1 a
e2 <- lookup k2 a
if elem (e1, e2) f then return [Just a] else return []
即
fromMaybe
答案 1 :(得分:2)
如果我能正确理解这个问题,我认为这是可能的。
让我感到震惊的是,您正试图跟踪两种不同类型的失败,空列表表明最终的elem
查找失败。 Maybe
表示(1)原始Maybe Assignment
为Nothing
或(2)lookup
失败。我们可以更明确地说明这一点。返回类型应该类似于
data FailureType = Existence | SeenInF
Either FailureType Assignment
然后,我们只需使用errors模块将Maybe
类型的失败转换为Either
。
import Control.Error
predi2 :: [(Val, Val)] -> Ref -> Ref -> Maybe Assignment -> Either FailureType Assignment
predi2 f k1 k2 ma = do a <- note Existence ma
e1 <- note Existence $ lookup k1 a
e2 <- note Existence $ lookup k2 a
note SeenInF $ guard $ (e1, e2) `elem` f
return a
这个解决方案有点奇怪,因为它涉及两个故障单子Maybe
和Either
之间的转换,但note
是一个非常有用的功能。