Question

So I made these functions to swap the arguments of functions

swap1_3 f x y z = f z y x

toFront3 f x y z = f z x y

These functions work as follows

foo x y z = [x,y,z]
a = foo 1 2 3 -- returns [1,2,3]
b = swap1_3 foo 1 2 3 -- returns [3,2,1]
c = toFront3 foo 1 2 3 -- returns [3,1,2]

Now, what I don't understand are the type signatures of these functions.

The type signatures are as follows

swap1_3 :: (a -> b -> c -> d) -> c -> b -> a -> d

toFront3 :: (a -> b -> c -> d) -> b -> c -> a -> d

From just looking at

swap1_3

one would think that

a corresponds to the type of x
b corresponds to the type of y
c corresponds to the type of z
d corresponds to the return type of f

but, when you look at the second half of the the type signature of

toFront3

it seems like there isn't that correspondence.

So, what's going on here?

Was it helpful?

Solution

It's a bit confusing, but look at it this way

f       :: a -> b -> c -> d
f z     ::      b -> c -> d
f z x   ::           c -> d
f z x y ::                d

Which implies

z :: a
x :: b
y :: c

So, we have

toFront3
    :: (a -> b -> c -> d)       -- f
    -> b                        -- x
    -> c                        -- y
    -> a                        -- z
toFront3 f x y z = f z x y

OTHER TIPS

I'm often confused by the types of these sorts of function-transforming functions for a minute before I think about them. Another good way of looking at them is to add unnecessary parentheses to their types, and look at them like this:

toFront3 :: (a -> b -> c -> d) -> (b -> c -> a -> d)

That is, toFront3 takes a function of 3 arguments, and gives you a function of the same arguments in a different order.

To have some names:

let g = toFront3 f

g and f are both functions of 3 arguments. g is going to call f after shuffling its 3rd argument to the front. Therefore the arguments g will receive are the pre-shuffled arguments. So to go from f :: a -> b -> c -> d to the type of g we have to apply the inverse shuffling of arguments that toFront3 does, so that shuffling them will restore the argument order to a -> b -> c -> d, as is required to be passed to f post-shuffle.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top