riccardotommasini / ppl

This repository contains the material related to the practical classes of the course Principles of Programming Languages
Apache License 2.0
29 stars 12 forks source link

Did I get this right? #7

Open leonardoarcari opened 6 years ago

leonardoarcari commented 6 years ago

I don't know if this is a meaningful comment but I was reasoning for a hour an half on this piece of code to understand it properly and I think I got somewhere. I'd like to check with you if my reasoning is correct.

I was trying to justify why the code is working by taking a look at the type of the <*> operator. So the signature is: (<*>) :: Applicative f => f (a -> b) -> f a -> f b And we implement it for State this way: (State f) <*> (State d) = ...

Because State is of kind * -> * -> * it is parametric in 2 types, while the Applicative operator requires an applicative of kind * -> *. So we overload the applicative class for State by making it parametric with this line: instance Applicative (State s) where ...

So, in the overloading of <*> for State, the types a and b in f (a -> b) -> f a -> f b refer to the result types of States! Namely the a in newtype State st a = State {runState :: st -> (a, st)}. Here's why we can write the following line of code: ... in (f' f'', s'') ...

In this code, f' is the result of the left-hand-side operand of <*> which, by definition of <*>, has type (a -> b) so it is a function. Hence we can apply it to the result of the right-hand-side operand which is of type a.

That wasn't clear to me at the first place, I'm not sure whether this was stated in the class because I missed it but it took me a while to figure that out. And it may be wrong. I'd appreciate some feedback on this to check if what I said is true. Thanks.

https://github.com/riccardotommasini/ppl/blob/a61508c10c2596f1b8d5531a647bce8048182630/haskell/Prepared/ESE20171205.hs#L32-L47

riccardotommasini commented 6 years ago

You got it right :)