Last active
March 9, 2020 01:02
-
-
Save techtangents/4089e563352b4678944c to your computer and use it in GitHub Desktop.
join bimap explanation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Consider the function type constructor "->" in infix form: | |
-- e.g. "a -> b" is the same as "(->) a b" | |
-- Partially applied, "(->) a" is the "reader" type, | |
-- i.e. functions that "read" an 'a'. "(->) a" is a Monad - the Reader Monad. | |
-- Consider the join function: | |
join :: Monad m => m (m a) -> m a | |
-- replace a with b: | |
join :: Monad m => m (m b) -> m b | |
-- Add some parens: | |
join :: Monad m => (m (m b)) -> (m b) | |
-- Now specialise to Reader Monad: just textually replace m with ((->) a) | |
join :: (((->) a) (((->) a) b)) -> (((->) a) b) | |
-- (->) is right-associative, so we can drop some parens: | |
join :: ((->) a ((->) a b)) -> ((->) a b) | |
-- Then change to infix: | |
join :: (a -> a -> b) -> a -> b | |
-- Now, you passed "bimap" to join. bimap is: | |
bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d | |
-- and we're passing this as the (a -> a -> b) argument. | |
bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d | |
-- ( a ) -> ( a ) -> ( b ) | |
-- To fit this type signature, bimap specialises to: | |
bimap :: Bifunctor p => (a -> b) -> (a -> b) -> p a a -> p b b | |
-- We're using this on "uncurry (/)", so our bifunctor is pair, so bimap specialises further to: | |
bimap :: (a -> b) -> (a -> b) -> (a,a) -> (b,b) | |
-- So, "join bimap", specialised to pairs is: | |
join bimap :: (a -> b) -> (a,a) -> (b,b) | |
-- A pair (a,a) is a vector of length 2, so "join bimap" is the fmap for this type! | |
-- Pair already has a Functor, so let's newtype it to demonstrate the vector's Functor: | |
newtype Vec2 a = Vec2 (a,a) deriving Show | |
instance Functor Vec2 where | |
fmap f (Vec2 p) = Vec2 $ join bimap f p | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment