Вопрос о композиции функций Haskell

Если это работает:

Prelude Data.Char> map toUpper ("sdfsd" ++ "dfgfdg")
"SDFSDDFGFDG"

Тогда, почему это не делает?

Prelude Data.Char> map toUpper . (++) "sdfsd" "dfgfdg"

<interactive>:1:14:
    Couldn't match expected type `a -> [Char]'
           against inferred type `[Char]'
    In the second argument of `(.)', namely `(++) "sdfsd" "dfgfdg"'
    In the expression: map toUpper . (++) "sdfsd" "dfgfdg"
    In the definition of `it': it = map toUpper . (++) "sdfsd" "dfgfdg"
9
задан artemave 2 March 2010 в 12:21
поделиться

2 ответа

map toUpper . (++) "sdfsd" "dfgfdg"

разбирается как:

(map toUpper) . ((++) "sdfsd" "dfgfdg")

Итак, в основном вы делаете

(map toUpper) . "sdfsddfgfdg"

Это не работает, потому что второй аргумент . должен быть функцией, а не строкой.

Я предполагаю, что вы пытались сделать что-то вроде (map toUpper. (++)) "sdfsd" "dfgfdg" . Это также не работает, потому что тип возвращаемого значения ++ - [a] -> [a] , а тип аргумента map toUpper - [a] .

Дело в том, что хотя можно представить ++ как функцию, которая принимает два списка и возвращает список, на самом деле это функция, которая принимает один список, а затем возвращает функцию, которая принимает другой. list и возвращает список. Чтобы получить то, что вы хотите, вам потребуется ++ в функцию, которая принимает кортеж из двух списков и возвращает список. Это называется «не торопиться». Следующие работы:

map toUpper . (uncurry (++)) $ ("sdfsd", "dfgfdg")
13
ответ дан 4 December 2019 в 10:31
поделиться

Вы хотите $ вместо . : map toUpper $ (++) "sdfsd" "dfg" работает и делает то, что вы хотите. Причина этого в том, что $ - это приложение-функция с очень низким приоритетом, поэтому исправленная версия читается следующим образом: «Примените функцию map toUpper к результату (+ +) "sdfsd" "dfg" ".

7
ответ дан 4 December 2019 в 10:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: