2013-09-13 3 views
3

Рассмотрим следующую функцию лямбда в Haskell:Что возвращает следующая функция лямбды в Haskell?

(\x g n -> g (x * n)) 

Он принимает два параметра: Num имени x и функция g которая принимает Num имени n и возвращает что-то другое. Лямбда-функция возвращает другую функцию того же типа, как g:

(\x g n -> g (x * n)) :: Num a => a -> (a -> t) -> a -> t 

То, что я не понимаю, что означает выражение g (x * n) на самом деле представляют. Для примера рассмотрим следующий случай использования:

((\x g n -> g (x * n)) 2 id) 

В этом случае x является 2 и g является id. Однако что такое n? Что представляет собой g (x * n)? Путем простой подстановки его можно свести к id (2 * n). Это то же самое, что и id . (2 *)? Если да, то почему бы просто не написать (\x g -> g . (x *))?

+3

функция принимает * три * параметры. – chirlu

ответ

7

Я собираюсь противоречить чирлу. (\x g n -> g (x * n)) - функция одного аргумента.

Поскольку все функции принимают только один аргумент. Просто функция возвращает другую функцию, которая возвращает другую функцию.

Обессахаренный, это то же самое, как

\x -> \g -> \n -> g (x * n) 

который довольно близок к типу

Num a => a -> (a -> b) -> a -> b 

Расширение вашего использования:

(\x g n -> g (x * n)) 2 id 

Разложим что

(\x -> \g -> \n -> g (x * n)) 2 id 

Что такое же, как

((\x -> \g -> \n -> g (x * n)) 2) id 

Теперь мы можем применить внутреннюю функцию аргумента, чтобы получить

(let x = 2 in \g -> \n -> g (x * n)) id 

или

(\g -> \n -> g (2 * n)) id 

Теперь мы можем применить эту функцию его аргумент для получения

let g = id in \n -> g (2 * n) 

или

\n -> id (2 * n) 

Который, с помощью осмотра, мы можем констатировать, что эквивалентно

\n -> 2 * n 

Или, точечно бесплатно

(2*) 
1

Вы близко. Последний пример, который вы дали, ((\x g n -> g (x * n)) 2 id) представляет собой частичное применение функции. Он имеет подпись типа Num a => a -> t и эквивалентен следующему: \n -> id (2 * n).

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