Question

Assuming I have the following types:

data Test = Test1 | Test2
            deriving (Eq, Show)

data TestDS = TestDS {
      testField1 :: String,
      testField2 :: Test
    } deriving (Eq, Show)

testFilter :: [TestDS] -> [TestDS]
testFilter tdata = filter (\x -> testField2 x == Test2) tdata

Is it possible to convert the above filter function to the following form:

filter (Test2 == testField2) tdata

(The above filter function of course produces a compile error)

Was it helpful?

Solution

Is this what you want?

filter ((Test2 ==) . testField2) tdata

Remember that (Test2 ==) and testField2 are both functions that can be composed.

OTHER TIPS

filter (\x -> testField2 x == Test2) tdata

It seems you put parentheses incorrectly in your mind. The code is not

filter ((\x -> testField2 x) == Test2) tdata

It is really

filter (\x -> (testField2 x == Test2)) tdata

So eta-reduction rule ("\x -> foo x can be replaced with foo") is not applicable.

To have it applicable you need to move x to the end of lambda body. Firstly we use commutativity of ==:

filter (\x -> (Test2  == (testField2 x))) tdata

I put extra parentheses to clarify that eta-reduction is still not applicable. Now the idea is to apply function composition rule ("foo (bar x) can be replaced with foo . bar"), but to demonstrate what are foo and bar in our example I will use prefix form of ==:

filter (\x -> ((==) Test2 (testField2 x))) tdata

Now it's clear that foo is (==) Test2 and bar is textField2:

filter ((==) Test2 . testField2)) tdata

Now instead of (==) Test2 we can use so called operator section. (== foo) (parentheses are mandatory) is the same as \x -> x == foo. (foo ==) is the same as 'x -> foo == x.

filter ((== Test2) . testField2)) tdata

or

filter ((Test2 ==) . testField2)) tdata

You can say

filter ((Test2 ==) . testField2) tdata

or also (my preference) use a list comprehension:

[ t | t@TestDS{testField2 = Test1} <- tdata ]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top