You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
21 lines
871 B
21 lines
871 B
7 years ago
|
# Wait, how does that even typecheck
|
||
|
|
||
|
```
|
||
|
(.) :: (b -> c) -> (a -> b) -> a -> c
|
||
|
-- fmap fmap
|
||
|
fmap :: Functor f => (m -> n) -> f m -> f n
|
||
|
fmap :: Functor g => (x -> y) -> g x -> g y
|
||
|
```
|
||
|
Let's typecheck `fmap . fmap.`.
|
||
|
|
||
|
1. First, it's important to note that `fmap` is a function that takes a function `m -> n` and returns a function `f m -> f n`.
|
||
|
2. Using that information we see that `a` is actually `m -> n`.
|
||
|
3. We also see that `b` is actually `f m -> f n` **and** `x -> y`, so `x` has to be `f m` and `y` has to be `f n`.
|
||
|
4. We can then also conclude that `g x` is `g (f m)` and `g y` is `g (f n)`
|
||
|
|
||
|
Armed with this knowledge, we can apply fmap to (.) a first time
|
||
|
`(fmap.) :: (Functor g) => (a -> (f m -> f n)) -> a -> g (f m) -> g (f n)`
|
||
|
|
||
|
And now we apply it a second time:
|
||
|
`(fmap . fmap) :: (Functor g, Functor f) => (m -> n) -> g (f m) -> g (f n)`
|