I was having a look at some list operations and came across !!
:
(!!) :: [a] -> Int -> a
xs !! n
| n < 0 = negIndex
| otherwise = foldr (\x r k -> case k of
0 -> x
_ -> r (k-1)) tooLarge xs n
The function (\x r k -> ...)
has type a -> (Int -> a) -> Int -> a
, but foldr
takes a function that should only accept two arguments:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
Can someone explain to me why foldr
accepts a function that takes 3 arguments with the following type a -> (Int -> a) -> Int -> a
? Especially since the result should have the same type as the second argument?
->
is right-associative. So a -> b -> c
is a -> (b -> c)
. Therefore, your type
a -> (Int -> a) -> Int -> a
is the same as
a -> (Int -> a) -> (Int -> a)
and we can see that it fits foldr
's type quite well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With