Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a function based on its type?

I'm trying to define a simple Haskell function with the type (m -> n -> l) -> (m -> n) -> m -> l. I thought that it needs be to defined as f g h x = f g (h x), but apparently that's not true. How could I correct this function?

like image 530
Andrea Berger Avatar asked Nov 19 '25 00:11

Andrea Berger


2 Answers

Based on the signature, the only sensical implementation is:

f :: (m -> n -> l) -> (m -> n) -> m -> l
f g h x = g x (h x)

This makes sense since we are given two functions g :: m -> n -> l and h :: m -> n, and a value x :: m. We should construct a value with type l. The only way to do this is to make use of the function g. For the parameter with type m we can work with x, for the second parameter we need a value of type n, we do not have such value, but we can construct one by applying h on x. Since h x has type h x :: n, we thus can use this as second parameter for g.

This function is already defined: it is a special case of (<*>) :: Applicative f => f (n -> l) -> f n -> f l with f ~ (->) m.

Djinn is a tool that reasons about types and thus is generating function definitions based on its signature. If one queries with f :: (m -> n -> l) -> (m -> n) -> m -> l, we get:

f :: (m -> n -> l) -> (m -> n) -> m -> l
f a b c = a c (b c)

which is the same function (except that it uses other variable names).

like image 133
Willem Van Onsem Avatar answered Nov 20 '25 19:11

Willem Van Onsem


f :: (m -> n -> l) -> (m -> n) -> m -> l
f    g                h           x  = _

Now you need to use the arguments in some way.

   g (_ :: m) (_ :: n) :: l
   h (_ :: m) :: n
   x :: m

Both g and h need a value of type m as their first argument. Well, luckily we have exactly one such value, so it's easy to see what to do.

   g x (_ :: n) :: l
   h x :: n
   x :: m

So now g still needs a value of type n. Again we're lucky, because applying h to x has produced such a value.

   g x (h x) :: l
   h x :: n
   x :: m

Ok, and there we now have something of type l, which is what we needed!

f g h x = g x (h x)
like image 32
leftaroundabout Avatar answered Nov 20 '25 20:11

leftaroundabout



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!