I have run these haskell function in ghci then got those output, but i dont know how to explain it. What is the difference between g(x,y) and g(x y) and how the yield that output.
*Main> let j g (x, y) = g(x,y)
*Main> :t j
j :: ((a, b) -> t) -> (a, b) -> t
*Main> let j g (x, y) = g(x y)
*Main> :t j
j :: (t1 -> t2) -> (t3 -> t1, t3) -> t2
What is the difference between
g(x,y)andg(x y)and how the yield that output.
Well Haskell has - compared to the gross of programming languages - an "unusual" syntax (compared to very common languages like C, Java, etc.) how to describe function applications.
f x is a function application with f the function, and x the parameter. The parentheses are not necessary (in contrast to for example programming languages like C, Java, C#, etc.), however they may be included. Therefore f(x) is interpreted as f (x) and since (x) is simply x, the two are equivalent.
With that in mind if we look at g (x y) we see two function applications: x y, and g (x y). In a programming language like Java, this would look like g(x(y)). g, and x are thus both functions (where the "output type" of x should be the same as the "input type" of g). We perform function application with x the function and y the parameter, and the result is a parameter in a function application with g the function.
Haskell also has tuples. For example (4, 2) a 2-tuple. (x, y) is a 2-tuple as well: x is the first element, and y the second. If we thus write g (x, y), then we perform a function application with g the function, and (x, y) (a 2-tuple) the parameter. So that means that x has type a, and y has type b, then g has type (a, b) -> c.
With that in mind, we can derive the signature of functions, for example:
j g (x, y) = g (x,y)
We see here that j has "two" parameters (in Haskell all functions have one parameter, the result of that function takes then another parameter), so we start by describing the signature of the function as:
j :: a -> b -> c
g :: a
(x, y) :: b
g (x, y) :: c
Since (x, y) is a tuple, we specialize the type of (x, y) as (d, e), so that means that the signature changes to:
j :: a -> (d, e) -> c
g :: a
(x, y) :: b ~ (d, e)
g (x, y) :: c
x :: d
y :: e
(the tilde ~ stands for the fact that the two types are the same)
Since we call g with (x, y) as parameter, we know that g is a function. The input type is the type of the parameter (x, y), so (d, e), whereas its result type is here the type of the result of j g (x, y), hence c, so we derive that g has type (d, e) -> c, so that means that:
j :: ((d, e) -> c) -> (d, e) -> c
g :: a ~ ((d, e) -> c)
(x, y) :: b ~ (d, e)
g (x, y) :: c
x :: d
y :: e
Then all constraints are satisfied, hence the type of j is:
j :: ((d, e) -> c) -> (d, e) -> c
I leave deriving the type of j g (x, y) = g(x y) as an exercise.
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