У меня есть объявление функции высшего порядка, чтобы дважды применить функцию, заданную в качестве аргумента:
twice :: (a -> a) -> a -> a
twice f x = f (f x)
Путаница исходит из этой сессии GHCi:
*Main> let _4 = twice twice
*Main> let __4 = twice twice (*2)
*Main> let _16 = _4 _4
*Main> let __16 = _4 __4
*Main> _16 (*2) 2
231584178474632390847141970017375815706539969331281128078915168015826259279872
*Main> __16 2
131072
Это довольно ясно с __16
, потому что происходит просто «умножение» этого вызова функции, поэтому мы фактически получим (2 ^ 16) * 2
после его вызова. Насколько я понимаю, это происходит потому, что функция, заданная в качестве параметра, уже применяется частично, поэтому тип __4 и __16 равен (Num a) => a -> a
.
Но результат вызова _16
с данной функцией и целочисленными аргументами просто приводит меня в замешательство. Я могу понять, что типы _4
и _16
являются необработанными (они равны сигнатуре twice
функции, но вложены под капот), но это не дает мне понятия о том, почему результаты так сильно отличаются. Я просто не могу получить семантику программы после предоставления функции, которая частично не применяется в качестве аргумента.
Может кто-нибудь объяснить, почему этот номер просто так здорово?