Почему использование оператора композиции позволяет избежать явной ссылки на начальный аргумент? - PullRequest
1 голос
/ 18 июня 2019

Я не могу понять, почему приведенный ниже код не скомпилируется:

decode :: [Bit] -> String
decode xs = map  (chr . bin2int) . (chop8 xs)

Но ниже будет:

decode :: [Bit] -> String
decode = map  (chr . bin2int) . chop8 

Когда мы дадим 2-ю функциюсписок, он применяет к нему chop8, затем сопоставляет (chr. bin2int) с элементами в созданном списке.

Так почему же первый пример не делает то же самое?Разве мы не делаем то же самое, а просто даем chop8 аргумент в определении функции?

Спасибо

Ответы [ 2 ]

9 голосов
/ 18 июня 2019

Определение (.) является ключевым здесь.

Чтобы привести более простой пример:

decode1, decode2 :: Int -> Char
decode1 x = chr . (abs x)
decode2 = chr . abs

Теперь определение (.) равно f . g = \a -> f (g a), поэтому мы можем использовать это в обоих наших определениях:

decode1 x = \a -> chr (abs x a)
decode2 = \x -> chr (abs x)

Мы можем еще больше упростить это, переместив лямбда-параметры в соответствие шаблону:

decode1 x a = chr (abs x a)
decode2 x = chr (abs x)

Очевидно, decode2 - правильная функция; decode1 даже не проверяет тип. abs принимает только один аргумент, но decode1 вызывает его с 2! Кроме того, decode1 имеет дополнительный параметр, a, который нам не нужен.

4 голосов
/ 18 июня 2019

Вторая версия, использующая так называемый стиль без точек, не требует параметра "xs", потому что выражение map (chr . bin2int) . chop8 уже производит функцию типа [Bit] -> String - так что все, что вам нужно, это установить decode = к значению выражения.

В первой версии вы явно передаете аргумент xs, поэтому выражение справа = должно иметь тип Int. Поскольку вы явно применяете chop8 к xs, результатом является конкретный список, а не функция.

Одним из решений является явное применение карты к результату chop8:

decode xs = map  (chr . bin2int) $ (chop8 xs)

Обратите внимание на замену . на $ - «применить функцию к параметру» вместо «создать функцию с другой функцией»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...