2010-11-04 2 views
2
> map (++ "!") ["a", "b", "c"] 
["a!","b!","c!"] 
> (++) "!" "a" 
"!a" 

Эти две линии для меня не имеют смысла. При использовании ++ в map, кажется, что первый параметр добавляется ко второму, но во втором списке это наоборот. Как Хаскелл рассуждает о поведении в функции map?Как работает частное приложение?

ответ

9

(++ "!") - это немного специальный синтаксис, называемый operator section. Частично применяется параметр второй оператора инфикса, тогда как (++) "!" работает как обычное частичное приложение и применяет первый параметр.

Вы также можете сделать то же самое с регулярными функциями, используемыми в стиле infix с обратными зажимами: (`map` [1..3]) эквивалентен (\f -> map f [1..3]).

Кажется странным, потому что это особая особенность, которая присутствует там только потому, что это чертовски полезно.

+1

Стоит также отметить, что '("! "++)' тоже является законным, что совпадает с '\ x ->"! " ++ x'. –

+0

@Antal: В Haskell 98, да. Но по соображениям производительности GHC делает вместо этого только '(++)"! "', Что может привести к некорректному кэшированию выражения. – fuz

+0

True, что также позволяет использовать постфиксные операторы с этим синтаксисом (хотя я думаю, что для этого требуется опция GHC); однако, для объяснения концепции, определения одной запутанной вещи в терминах того, с чем она смущается, вероятно, не помогает :-) –

2

Частичное применение (++ "!") идентично (\x -> x ++ "!"). Другими словами, выражение (++ "!") достаточно умен, чтобы знать, что "!" является вторым аргументом (++). Он знает это, потому что знает, что ++ является оператором инфикса. Во втором выражении (++) "!" "a" идентичен "!" ++ "a" и делает то, что вы ожидаете.

2
map (++ "!) ["a", "b", "c"] 

эквивалентно

["a" ++ "!", "b" ++ "!", "c" ++ "!"] 

И

(++) "!" "a" 

эквивалентно

"!" ++ "a" 

Надеется, что это помогает.

+0

Но если '(++)"! " «a» 'равнозначно' '!" ++ "a", то почему он не отображает список во второй параметр? Это только частный случай для инфиксных функций? – ryeguy

+0

Это связано с тем, как карта воспринимает вещи. Карта будет конкатенировать всегда элемент списка с «!», А не наоборот. –

+3

Это не имеет ничего общего с 'map'. '(++"! ")" a "' равнозначно '(" a "++"! ")'. –

Смежные вопросы