Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using filter with custom datatypes

Tags:

haskell

filter

I have these datatypes:

data Command = Back Int | Front Val deriving (Show,Eq)
data Val = Val {first::Int, second::Int, third::Int} deriving (Show, Eq)
type Program = [Command]

I have this function:

foo :: Program -> Int
foo list = length (filter (==Front Val {first, second, third}) list)

The purpose is to find how many times a Front occurs USING FILTER ONLY, and foo gives compilation error. I am not sure how to represent the integer/val part of Front.

like image 249
Bhushan Oza Avatar asked Mar 22 '26 21:03

Bhushan Oza


1 Answers

You can not use an equality check (==) :: Eq a => a -> a -> Bool with variables like first and second, if these do not have a value. What you need here is pattern matching.

We can for example use list comprehension:

foo :: Program -> Int
foo list = length [ v | v@(Front _) <- list ]

There is no need to match the parameter with Val {}, or Val _ _ _, etc. since the only data constructor for the Val type is Val.

In case you think you will later add more data constructors, you can however add an extra subpattern:

foo :: Program -> Int
foo list = length [ v | v@(Front (Val {})) <- list ]

Or we can do the pattern matching in a function and use filter :: (a -> Bool) -> [a] -> [a], like:

foo :: Program -> Int
foo = length . filter f
    where f (Front _) = True
          f _ = False

or if we include the Val data constructor check:

foo :: Program -> Int
foo = length . filter f
    where f (Front (Val {})) = True
          f _ = False
like image 112
Willem Van Onsem Avatar answered Mar 24 '26 20:03

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!