2013-12-20 3 views
2

Предполагая, что у меня есть следующие типы:Simplify анонимные функции в функции порядка Higer

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 в конец лямбда-тела. Во-первых, мы используем коммутативности ==:

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

я ставлю дополнительные скобки, чтобы уточнить, что ета-восстановительная еще не применяется. Теперь идея состоит в том, чтобы применить правило функции композиции («foo (bar x) можно заменить foo . bar»), но и продемонстрировать, что является foo и bar в нашем примере я буду использовать префикс форму ==:

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

Теперь стало ясно, что foo является (==) Test2 и bar является textField2:

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 ] 
Смежные вопросы