2013-12-20 33 views
2

簡化匿名函數假設我有以下幾種類型:在海格順序功能

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 

是否有可能在上述過濾器的功能轉換爲以下形式:

filter (Test2 == testField2) tdata 

(以上濾波器功能當然會產生編譯錯誤)

回答

9

這是你想要的嗎?

filter ((Test2 ==) . testField2) tdata 

請記住,(Test2 ==)和testField2都是可以組成的函數。

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

看來你把括號錯誤地放在了你的腦海裏。代碼並不

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

這實在是

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

所以ETA還原規則( 「\x -> foo x可以foo更換」)是不適用的。

要使它適用,您需要將x移動到lambda主體的末尾。首先,我們使用的==可交換:

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

我把額外的括號來澄清ETA-削減幅度仍然是不適用的。現在的想法是應用函數組合規則(「foo (bar x)可以用foo . bar更換」),但表現出什麼foobar在我們的例子中,我將使用的==前綴形式:

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

現在很明顯, foo(==) Test2bartextField2

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

現在不是(==) Test2我們可以使用所謂的操作部分。 (== foo)(括號是強制性的)與\x -> x == foo相同。 (foo ==)與'x -> foo == x相同。

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

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

你可以說

filter ((Test2 ==) . testField2) tdata 

或也(我的偏好)使用列表理解:

[ t | [email protected]{testField2 = Test1} <- tdata ]