使用list comprehension来构建一个函数

时间:2016-08-16 14:37:40

标签: haskell list-comprehension

我用Haskell写了一个函数来从这个数据类型中提取一些值:

data Result = ResuVal Double     
              | ResuValIdx Double (Maybe Int)   
              | ResuValCpt Double Int           
              | NoResu                  
              deriving (Show)

此函数提取Int数据类型中的Result值,并将它们连接在一个列表中。

catIdxCpt :: [Result] -> [Int]
catIdxCpt [] = []
catIdxCpt (x:xs) = case x of
                ResuValIdx v (Just i) -> i:catIdxCpt xs
                ResuValCpt v c -> c:catIdxCpt xs      
                _ -> catIdxCpt xs  

这个功能运行良好,但我首先尝试用理解列表编写它,例如:

catIdxCpt ls = [i | ResuValIdx v (Just i)  <- ls  ]

catIdxCpt ls = [i | ResuValIdx v (Just i)  <- ls | ResuValCpt v i  <- ls ]

和其他组合。但我没有达到预期的效果。

您是否知道如何构建(如果可能)具有列表理解的catIdxCpt函数?

2 个答案:

答案 0 :(得分:4)

您的功能涉及映射和过滤,因此请考虑以下技术:

foo xs = [ y | Just y <- map go xs ]
  where go (ResuValIdx _ (Just i)) = Just i
        go (ResuValCpt v c)        = Just c
        go _                       = Nothing

辅助函数go会为要删除的元素返回Nothing

模式Just y <- zs将仅从列表zs中选择与模式Just y匹配的元素。

答案 1 :(得分:1)

[x | l <- ls, x <- [i | ResuValIdx v (Just i) <- [l]] ++ [i | ResuValCpt v i <- [l]]]

或者,考虑:

{-# LANGUAGE LambdaCase #-}

catIdxCpt :: [Result] -> [Int]
catIdxCpt = mapMaybe $ \case
  ResuValIdx v (Just i) -> Just i
  ResuValCpt v c -> Just c
  _ -> Nothing