JeanJouX
JeanJouX

Reputation: 2741

Use list comprehension to build a function

I wrote a function with Haskell to extract some values from this data type :

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

This function extract the Int values in the Result data type and concatenate them in a list.

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  

This function is working well but I first tried to wrote it with a comprehension list such as :

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

or

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

and other combinations. But I didn't managed to have the expected result.

Do you know how to built (if it is possible) the catIdxCpt function with a list comprehension ?

Upvotes: 3

Views: 307

Answers (2)

ErikR
ErikR

Reputation: 52057

Your function involves both mapping and filtering, so consider this technique:

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

The helper function go returns Nothing for elements you want to remove.

The pattern Just y <- zs will select only those elements from the list zs which match the pattern Just y.

Upvotes: 4

Gurkenglas
Gurkenglas

Reputation: 2317

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

Alternatively, consider:

{-# LANGUAGE LambdaCase #-}

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

Upvotes: 1

Related Questions