简体   繁体   中英

Simplifying Record pattern matching inside filter

Consider the following example:

data TestType = Free | Occupied { oc_field1 :: Int,
                                  oc_field2 :: Int,
                                  oc_field3 :: Int,
                                  oc_field4 :: Int
                                }

type SampleTest = [TestType]

filterOccupied :: SampleTest -> SampleTest
filterOccupied test = filter (\x -> case x of
                                 Occupied _ _ _ _ -> True
                                 Free -> False ) test

In the above example, inside filterOccupied I have to use four _ for matching Occupied type.

This becomes really painful when the records has more than ten fields. Is there a better way to do this ?

You can use {} pattern instead.

filterOccupied :: SampleTest -> SampleTest
filterOccupied test = filter (\x -> case x of
                                 Occupied {} -> True
                                 Free -> False ) test

Adding to snak's answer, this might also be easier with a list comprehension:

filterOccupied :: SampleTest -> SampleTest
filterOccupied test = [x | x@(Occupied {}) <- test]

Only items that match the pattern are retained in the list.

What about:

data TestType = Free
              | Occupied { oc_field1 :: Int
                         , oc_field2 :: Int
                         , oc_field3 :: Int
                         , oc_field4 :: Int
                         }
    deriving Eq

filterOccupied :: [TestType] -> [TestType]
filterOccupied = filter (Free/=)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM