Skip to content

Instantly share code, notes, and snippets.

@bond15
Created October 26, 2020 19:20
Show Gist options
  • Save bond15/df1023316748453105163881a3382bd3 to your computer and use it in GitHub Desktop.
Save bond15/df1023316748453105163881a3382bd3 to your computer and use it in GitHub Desktop.
module FunctorExample where
import Prelude hiding (Functor)
-- an Option data type in haskell
-- this is used to avoid returning nulls
data Option a = Some a | None
-- 'a' is a type parameter
ex1 :: Option Int
ex1 = Some 7
ex2 :: Option Int
ex2 = None
ex3 :: Option Bool
ex3 = Some True
evenEx1 :: Bool
evenEx1 = even 7 --- results in False
-- If I have a function even :: Int -> Bool, how to i 'lift' it to even' :: Option Int -> Option Bool ??
even' :: Option Int -> Option Bool
even' (Some n) = Some (even n) -- unwrap the integer n , call even :: Int -> Bool on it, wrap the result (even n) in Some
even' None = None
even'Ex1 :: Option Bool
even'Ex1 = even' (Some 7) -- results in (Some False)
-- can I do this generically? lift a function f :: a -> b to f' :: Option a -> Option b? yes!
lift' :: (a -> b) -> Option a -> Option b
lift' f (Some a) = Some (f a)
lift' f None = None
liftEven :: Option Int -> Option Bool
liftEven = lift' even
-- liftEven (Some 7) results in (Some False)
-- so my definition of lifted even (even') is actually equal to lift' (even)
--even' = lift(even)
-- This is a general pattern, and types that obey this pattern are instances of Functors
class Functor f where
lift :: (a -> b) -> f a -> f b
-- This is a typeclass, is tells us that type 'f' has an implementation of 'lift'
-- we know that Option has this property so lets substitute it in for 'f'
instance Functor Option where
lift = lift' -- our definition above
ex4 :: Option Int -> Option Bool
ex4 = lift even
ex5 :: Option Bool
ex5 = (lift even) (Some 7) -- results in (Some False)
-- This is called a functor because it is a "function" that acts on types AND functions
-- Option takes type `a` to type `Option a`
-- a -> Option a
-- Option take function `a -> b` to `Option a -> Option b`
-- (a -> b) -> Option a -> Option b
-- ^^ the type of `lift
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment