List 通过分发[]简化代码

List 通过分发[]简化代码,list,haskell,monads,List,Haskell,Monads,我有以下功能 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

我有以下功能

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 ???]
predi2::[(Val,Val)]->Ref->Ref->(可能分配->[可能分配])
预测2 f k1 k2=[\ma->do
不,不是

我将更像这样编写您的
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 []
predi2f k1 k2 ma=fromMaybe[Nothing]$do

如果我正确理解这个问题,我认为这是可能的

让我印象深刻的是,您试图跟踪两种不同类型的失败,空列表表示最终的
元素查找失败。
可能
表示(1)原始
可能分配
或(2)
lookup
失败。我们可以更明确地说明这一点。返回类型应该是

data FailureType = Existence | SeenInF
Either FailureType Assignment
然后,我们将使用模块将
类型故障转换为
s

导入控制。错误
预测2::[(Val,Val)]->Ref->Ref->Maybe Assignment->任一故障类型赋值
predi2 f k1 k2 ma=执行a
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