I have a high-order function declaration to apply a function given as an argument twice:
twice :: (a -> a) -> a -> a
twice f x = f (f x)
The confusion comes from this GHCi session:
*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
It is kinda clear with __16
, because what's going on is just "multiplying" of this function call, so we'll actually get (2 ^ 16) * 2
after it's invocation. As far as I can understood it happens because function given as a parameter is already partially applied, so the type of either __4 and __16 is (Num a) => a -> a
.
But the result of invocation of _16
with given function and integer arguments just leads me into confusion. I can understand that the type of either _4
and _16
are raw (are equal to twice
function's signature, but are nested under the hood), but it gives me no clue about why the results differ so much. I just can't get program's semantics after providing a function that is not partially applied as an argument.
Can somebody please explain why is this number just SO GREAT?