Last active
November 29, 2015 21:06
-
-
Save Sam-Serpoosh/4a33af4686f2481312c7 to your computer and use it in GitHub Desktop.
This code snippet shows a very powerful concept provided by Haskell's type system.
This file contains 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
twice :: Int -> Int | |
twice = (*2) | |
twicePossibleNums :: Maybe [Int] -> Maybe [Int] | |
twicePossibleNums = (fmap . fmap) twice | |
main :: IO () | |
main = putStrLn $ show $ twicePossibleNums (Just [1, 2, 3]) -- => Just [2, 4, 6] | |
-- How it Works? | |
-- Maybe & List are Functors in Haskell: | |
-- class Functor f where | |
-- fmap :: (a -> b) -> f a -> f b | |
-- So in the case of Maybe and List `fmap` has the signature: | |
-- Maybe => fmap :: (a -> b) -> Maybe a -> Maybe b | |
-- List => fmap :: (a -> b) -> [a] -> [b] | |
-- Combining/Composing those two Functors will have: | |
-- Maybe [] => fmap :: (a -> b) -> Maybe [a] -> Maybe [b] | |
-- The outter Functor is Maybe and the inner one is List. | |
-- So we can leverage currying of List Functor's `fmap` with | |
-- our `twice` function to provide appropriately typed function | |
-- which can be used as the first argument* to Maybe Fucntors' | |
-- `fmap`: | |
-- (fmap twice) :: [Int] -> [Int] -- List Functor's `fmap` | |
-- fmap (fmap twice) :: Maybe [Int] -> Maybe [Int] -- Maybe Functor's `fmap` | |
-- So we have: | |
-- twicePossibleNums :: Maybe [Int] -> Maybe [Int] | |
-- twicePossibleNums = fmap (fmap twice) | |
-- Or: | |
-- twicePossibleNums = (fmap . fmap) twice |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This gives you the ability of composing different
single-responsible
units/types/typeclasses and handle more complicated situations with nested types etc. This is provided out of the box inHaskell
and for many different concepts and not just Functor.I can't help but thinking that these abstractions and concepts working very smoothly like this at different levels in Haskell, has a lot to do with the fact that they are inspired by Category Theory. Because it has the symphony of consistent abstractions/concepts working at different levels (categories, objects, morphisms, functors, category of "small" categories a.k.a Cat, etc.) in its DNA 😄