Is a function with a functional argument curried? - haskell

From https://stackoverflow.com/a/57020455/156458
In Haskell, it happens that everything is curried; all functions take just one argument (even uncurried functions in Haskell take a tuple, which is, strictly speaking, a single argument -- you might want to play with the curry and uncurry functions to see how that works).
I am not sure if that is true, but assume so.
If a function takes another function as an argument, is it curried or uncurried in a similar sense as a function taking a tuple or list argument being uncurried? (A pair tuple type is type1 x type2 and can be type1^2, while a function type is type2^{type1}, so I find them similar)
If uncurried, how can I convert such a function to a curried function?

If a function takes another function as an argument, is it curried or uncurried?
It takes just a function, so a single parameter, and hence it is curried. The fact that that parameter is a function is irrelevant.
Such a function is for example map. map has type:
map :: (a -> b) -> ([a] -> [b])
It thus takes a single parameter, a function (of type a -> b), and then returns a function [a] -> [b] that will map a list of as to a list of bs by applying that function.
So map show :: Show a => [a] -> [String] is the result of such function application, and this is again a function.

Yes, the quote is correct. All the talk about "curried" and "uncurried" functions is imprecise jargon.
Haskell is a curried language. Functions in Haskell always have exponential types. If an argument is a tuple, it doesn't matter, it is still just one value (which happens to be a tuple).
The concepts are approximated when we treat an (a,b) -> c Haskell function as the c a * b one. But it's just a mental gymnastics that we do.
What's actually curried or not, are programming languages. For instance, in Lisp,
(lambda (a b) c)
actually has the type c a * b and to turn it into the (c b)a function we need to put it through some transformations.
There actually is no (\a b -> c) lambdas in Haskell, only (\ a -> (\ b -> c)) nested lambdas(*) . When we write (\a b -> c) in Haskell, it is just a syntactical shortcut for (\ a -> (\ b -> c)). It is impossible to have actual (\a b -> c) lambda function in Haskell, though it is approximated by having (\(a,b) -> c) lambda function.
Where you really see the meaning of all this, if when you implement your own language with lambda functions.
Faced with a ((lambda (a b) c) x y z) function call, the real issue is how to pair-up the function's parameters and the values supplied.
Haskell converts it into ((let a=x in (let b=y in c)) z), but Lisp actually pairs up the parameters list (a b) with the list of values (x y z) and reports the length mismatch.
But, being the uncurried language that it is, Lisp is able to have the various twists and tweaks here, like optional arguments, default arguments, named arguments, etc., pairing up the parameters and the values in various different ways -- unlike Haskell, which always pairs up one parameter with one supplied value at a time.
(*) and with another crucial distinction: the a and b in Haskell's (\ a -> (\ b -> c)) are not variables, but patterns. They are not just assigned the values, like in Lisp -- they are matched up with them.

The truth I can see at least, is almost every value in haskell can be seen as a function with, and every function just take one parameter at the time. Let see an example (With Int as example, to be more clear):
f :: Int -> Int -> Int -> Int
f x y z = x + y + z
f can be seen as a function that takes a Int and returns a function
Int -> (Int -> Int)
:t (f 2)
(f 2) :: Int -> Int -> Int
:t (f 2 3)
(f 2 3) :: Int -> Int
(f 2 3) can be seen as a function that takes a Int and returns an Int
finally
:t (f 2 3 4)
(f 2 3 4) :: Int
An example with higher order functions:
h :: (Int -> Int -> Int) -> Int -> Int -> Int
h fn x y = fn x y
A little more complex but just the same idea:
:t (h f)
(h f) :: Int -> Int -> Int -> Int
(h f) is a function, expecting an Int , and returning (Int -> Int -> Int -> Int)
but... wait, was not it expecting to return a function? it should be so
(h f) :: Int -> Int -> (Int -> Int)
well, point made. let's continue
:t (h f 2)
(h f 2) :: Int -> Int -> Int
(h f 2) is a function expecting a Int and returning a function (Int -> Int)
and finally
:t (h f 2 3)
(h f 2 3) :: Int -> Int
(h f 2 3) indeed is a function, expecting a Int, returning an Int
(h f 2 3) 4 == 7
I think the conclusion here is, every function is curried in Haskell.

Related

Why `f x = x x` and `g x = x x x x x` have the same type

I'm playing with Rank-N-type and trying to type x x. But I find it counter intuitive that these two functions can be typed in the same way.
f :: (forall a b. a -> b) -> c
f x = x x
g :: (forall a b. a -> b) -> c
g x = x x x x x
I have also noticed that something like f x = x x ... x x (many xs) still has the same type.
Can anyone explain why it is the case?
The key is that x :: a -> b is a function that can provide a value of any type, no matter what argument is given. That means x can be applied to itself, and the result can be applied to x again, and so on and so on.
At least, that's what it promises the type checker it can do. The type checker isn't concerned about whether or not any such value exists, only that the types align. Neither f nor g can actually be called, because no such value of type a -> b exists (ignoring bottom and unsafeCoerce).
A simpler example
This is a phenomenon that can be observed whenever we use a variable which has a polymorphic type (like your x). The identity function id is perhaps the most famous example.
id :: forall a . a -> a
Here, all these expressions type check, and have type Int -> Int:
id :: Int -> Int
id id :: Int -> Int
id id id :: Int -> Int
id id id id :: Int -> Int
...
How is that possible? Well, the crux is that each time we write id we are actually meaning "the identity function on some unknown type a that should be inferred from the context". Crucially, each use of id has its own a.
Let's write id #T to mean the specific identity function on type T.
Writing
id :: Int -> Int
actually means
id #Int :: Int -> Int
which is straightforward. Instead, writing
id id :: Int -> Int
actually means
id #(Int -> Int) (id #Int) :: Int -> Int
where the first id now refers to the function space Int -> Int! And, of course,
id id id :: Int -> Int
means
(id #((Int -> Int) -> (Int -> Int))) (id #(Int -> Int)) (id #Int) :: Int -> Int
And so on. We do not realize that types get that messy since Haskell infers those for us.
The specific case
In your specific case,
g :: (forall a b. a -> b) -> c
g x = x x x x x
we can make that type check in many ways. A possible way is to define A ~ Int, B ~ Bool, T ~ (A -> B) and then infer:
g x = x #T #(T -> T -> T -> c) (x #A #B) (x #A #B) (x #A #B) (x #A #B)
I suggest to spend some time to realize that everything type checks. (Moreover our choices of A and B are completely arbitrary, and we could use any other types there. We could even use distinct As and Bs for each x, as long as the first x is suitably instantiated!)
It is then obvious that such inference is also possible even when x x x ... is a longer sequence.
This shouldn't really be any more surprising than the fact that
m :: (∀ a . a) -> (∀ a . a) -> (Int, Bool)
m p q = (p, q)
has the same type as
n :: (∀ a . a) -> (∀ a . a) -> (Int, Bool)
n p q = (q, p)
Much like in your example, this works because the universally-quantified argument can be used in lots of different way, with the compiler in each case choosing an appropriate type and enforcing x to act as having that type.
This is actually a rather contrived situation because types like ∀ a . a or ∀ a b . a->b are uninhabited (modulo ⊥), so you would never actually be able to use a RankN function with such an argument; pragmatically you wouldn't even write it either then!
Practically useful RankN functions usually impose some extra structure or typeclass constraint in their arguments, like
foo :: (∀ a . [a] -> [a]) -> ...
or
qua :: (∀ n . Num n => Int -> n -> n) -> ...

Is there a way to convert function type in haskell?

I am fairly new to haskell and I run into this problem with type converting a function. Let's say I don't know anything about a function other than its function type. Is it possible to convert its function type and put it as a new function.
For example
myfunc:: (Int -> Int -> Int) -> (Integer -> Integer -> Integer)
myfunc inputfunc = (function with type (Integer -> Integer -> Integer))
Are there ways to do such a thing?
Hints:
(Int -> Int -> Int) -> (Integer -> Integer -> Integer) can also be written (Int -> Int -> Int) -> Integer -> Integer -> Integer. It is a function of three arguments.
Converting Numbers
As already explained by others, what you want is basically this:
convert f x y = fromIntegral (f (fromIntegral x) (fromIntegral y))
This is pretty straightforward. However, if I were to do it, I'd take advantage of the on function from Data.Function, which converts the inputs of functions that take two arguments before applying it. So, in your example, it would look like this:
convert f x y = fromIntegral ((f `on` fromIntegral) x y)
I, personally, would go one step further and make this function point-free, but because on f fromIntegral expects two arguments, you can't just use (.), so I usually define an operator for this:
(.:) = (.) . (.)
You can figure out why this works on your own if you'd like, but now I can define convert as this:
convert f = fromIntegral .: (f `on` fromIntegral)
I feel that this is a lot more readable, but I am biased because I have been coding Haskell like this for a while now.
Also, if you look at the inferred type of this variable, you'd see that it's much more general than what you wanted:
convert :: (Integral a, Integral a1, Num b, Num b1) = (b1 -> b1 -> a) -> a1 -> a1 -> b
Anyway, I hope this is somewhat useful.
I really don't mean for this post to intimidate you as a newcomer, so if any of it confuses you, please ask me questions and I'd happily answer :)

Ghci error: No instance for Show

This works in the ghci
data MyList a = Empty | Cons a (MyList a) deriving (Show, Eq, Read, Ord)
let x = Cons(21, Cons(12, Empty))
However when I type:
Prelude> x
I get this error:
No instance for (Show (MyList (Integer, MyList (Integer, MyList a0) ->
MyList (Integer, MyList a0)) ->
MyList (Integer, MyList (Integer, MyList a0) ->
MyList (Integer, MyList a0)))) arising from a use of `print'
You are using the wrong syntax for function application. The following code does what you want:
let x = Cons 21 (Cons 12 Empty)
The reason for this is that the Cons constructor is a curried function, but you are treating it as an uncurried function.
Curried functions
Consider the following function adding two integers:
add :: Int -> (Int -> Int)
add = \x -> (\y -> x + y)
Here we say add is a function, which takes an argument x of type Int and returns a function,
which takes an argument y of type Int and returns x + y of type Int.
We can apply this function for example as (add 1) 2 evaluating to 3.
Function application is left-associative in Haskell, which means that we don't need the parentheses
in (add 1) 2 and can simply write add 1 2.
The function type constructor -> is right-associative in Haskell, which means that we don't need the parentheses in add :: Int -> (Int -> Int) and can simply write add :: Int -> Int -> Int.
Also we don't have to explicitly define add using lambdas and can use the following notation:
add :: Int -> Int -> Int
add x y = x + y
Encoding multi-parameter functions as single-parameter functions returning single-parameter functions is quite common in Haskell. This approach has the nice property, that we can also partially apply a function. For example the following function takes a single Int and adds 2:
add2 :: Int -> Int
add2 x = add 2 x
But we can also partially apply add and simply write:
add2 :: Int -> Int
add2 = add 2
This is also called point-free notation, where parameters are referred to as points.
Uncurried functions
An alternative encoding of multi-parameter functions can be done using tuple-values, i.e.
add' :: (Int, Int) -> Int
add' (x, y) = x + y
We can invoke this function for example as add' (2, 3), which constructs the pair (2, 3) :: (Int, Int) and passes it as a single argument to the add' function.
Uncurried <-> Curried
In the standard library are two functions to convert functions between the two styles.
curry :: ((a, b) -> c) -> a -> b -> c
curry f x y = f (x, y)
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f (x, y) = f x y
For example curry add' gives us add, and uncurry add gives us add'.
Back to explaining ghci's rambling
Note that we could also write the uncurried application as add'(2, 3), which together with partial application and polymorphism explains why let x = Cons(21, Cons(12, Empty)) doesn't directly lead to an error, but ghci subsequently says misterious things about the evaluation of x.
What happens here is that (12, Empty) is pair of type (Int, MyList a) for some type a.
This pair is then used as the first argument in Cons (12, Empty), so we get a partially applied function which takes
a MyList (Int, MyList a) and appends (12, Empty) as an element to this list.
The same happens for Cons(21, Cons(12, Empty)) where we partially apply a pair of 21 and the before mentioned partial function. In the end we tell ghci to print a function, which it cannot display and hence complains about a missing Show instance for the corresponding function type.

Returning a function in Haskell

In Haskell, is it possible to return a function from within a function? I tried searching on Hoogle for:
(a -> b) -> a -> b
but couldn't find any functions that could achieve this.
Yes, you can, and it's so common and deeply ingrained in the language that you don't even notice it!
For instance, when you write
mean :: Double -> Double -> Double
mean a b = (a + b) / 2
What you're really doing is, you define a function
mean :: Double -> EndoDouble
mean a = meanA
where meanA b = (a + b) / 2
where the type of meanA,
type EndoDouble = Double -> Double
happens to be a function type.
So, any "multi-parameter function" in Haskell really is a single-parameter function that returns a function! The concept is called Currying, you might have heard about it.
Treating functions as first-class citizens is one of the advantages of Haskell and doesn't require any special syntax.
For example if you want to have a function which will double the result of given function you can write:
doubleFunction f = (\x -> 2 * (f x))
When given a function f, doubleFunction is equal to a function which multiplies (f x) by 2. You can write it using function composition:
doubleFunction f = (* 2) . f
or even shorter:
doubleFunction = ((* 2) .)
doubleFunction is of type:
doubleFunction :: (Num a) => (a -> b) -> a -> b
Yes, you can: functions are values in Haskell, so it can be as simple as
functionIdentity :: (a -> b) -> a -> b
functionIdentity f = f
...which is just a specialised identity function.
You may also "explicitly" return a function by using a lambda if you wish, like const:
const x = \_ -> x

Function Composition Types

I struggle understanding function composition type results e.g
ghci> :t (id . const)
(id . const) :: a -> b -> a
ghci> :t ((:) . (+))
((:) . (+)) :: a -> [a -> a] -> [a -> a]
How do you guys generally derive function composition types?
That's simple, initially write down the types of both the functions:
> :t const
const :: a -> b -> a
> :t id
id :: a -> a
(id . const) gets translated to \x -> id (const x)
(const x) :: b -> a -- (Note that the type of `x` is `a` here)
id (const x) :: b -> a -- The output of id type will be the same as the input it takes
\x -> id (const x) :: a -> b -> a -- We aleady know the type of x
You can follow the same step for the next function.
Lets see that
> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
So in general:
Given two functions. Consider them as curried functions of one parameter, i.e. function of type
a -> b -> c -> ... -> z we'll consider as a function a -> ( b -> c -> ... -> z ) of one parameter that returns function with one parameter less.
Result type of second function should be same as parameter type of first. So consider parameter of first function as result parameter of second. Denote it as b.
Result type of whole composition should be equal a function from parameter type of second function (denote it as a) to result type of first function (denote it as c)
> :t (id . const)
> :t id
id :: a -> a
rename it to x -> x
> :t const
const :: a -> b -> a
Note that a here is not necessary the same that in previous type equation, some rename it to y -> z -> y
a = y
b = z -> y = x
c = x = z -> y
So result is a -> c = y -> ( z -> y) same as a -> b -> c
Overall semantics is equal to const
> :t ((:) . (+))
> :t (:)
(:) :: a -> [a] -> [a]
rename it to x -> [x] -> [x]
> :t (+)
(+) :: Num a => a -> a -> a
rename it to Num y => y -> y -> y
a = y
b = y -> y = x
c = [x] -> [x] = [y -> y] -> [y -> y]
Also we have restriction with type class Num y
So overall type well be Num y => a -> c = y -> [y -> y] -> [y -> y] same as Num a => a -> [a -> a] -> [a -> a]
Overall semantics is "make single parameter function that adds first parameter to numeric value and prepend that function to a given list of single parameter functions"
Exercises: Find the types of the function compositions below, by hand, not using GHCi. Do these exercises to build intuition for reasoning about function types. Remember that type a -> a, where a is a type variable, matches not only Int -> Int or [Bool] -> [Bool], but (a -> a) -> (a -> a) too. If you can't do the exercises, read below.
(*3) . (+2) (easy)
(*) . (+2)
(:) . (+2)
(:) . (*)
What is a function? It's something, that takes an input and returns an output. Not just random output, but output that depends on that input. For the same input the same function always returns the same output. A function transforms some stuff to another stuff. Input and output can be of different types. So imagine a function as a magical one-way tube: you put one thing in the hole labeled in and get something else from another hole named out, possibly of entirely different form. Like, you put a tomato in a tube and get a machine gun from the opposite end. But remember, functions are one-way, you can't put anything in the function's out hole.
a :: Int -> Int -- take a thing of type Int and return a thing of type Int
a n = n + 2
b :: Int -> Int
b n = n -- a function can even return the same value
c :: Int -> Bool -- an output can be of different type than input
c n = n `mod` 3 == 0
Haskell supports higher-order functions and is curried by default. This means that there are no multiple-argument functions in Haskell, every function accepts only 1 argument, but sometimes they can return functions. Haskell tubes always has one and only one hole in, but sometimes tubes pop tubes from the hole out! There are even tubes, in which you can put other tubes. Function types are right-associative, which means that a -> b -> c and a -> (b -> c) are the same thing.
:t (+) -- Num a => a -> a -> a
:t (:) -- a -> [a] -> [a]
So what's a function composition? It's when you compose functions into a new function, or when you fuse 2 tubes together, welding 1st's out to 2nd's in, so that whatever you put into the first tube's in hole, falls through and pops out of second tube's out hole.
A composed function then can be imagined as a long tube made out of two shorter tubes welded together. What would be the type of a composed function? Our new tube still has 2 holes in it, one labeled in, another labeled out. But remember, in of our new tube corresponded to in of a first part, and out of our new tube corresponded to out of the second part. So the type will be from whatever was input to 1st function to whatever was output of 2nd function.
:t (:[2,3]) . (+1) -- Num a => a -> [a]
-- why?
:t (+1) -- Num a => a -> a
:t (:[2,3]) -- Num a => a -> [a]
We joint 2 functions together, first's output to second's input, and get a new function that still has one input and one output. And that's exactly what function operator's type says:
:t (.) -- (b -> c) -> (a -> b) -> (a -> c)
Due to a historical accident, function composition goes from right to left, so (*3) . (+2) is a function that first adds 2 to a number, and then multiples by 3 the result. So how to deduce a type of a function composition? You joint the the input of 2nd function to an output of 1st function and throw away the types in between.
a -> b
b -> c becomes
a -> c
See also: [1], [2], [3], [4] for more ideas on how to use function composition and how to reason about function types.

Resources