Created
October 26, 2020 19:20
-
-
Save bond15/df1023316748453105163881a3382bd3 to your computer and use it in GitHub Desktop.
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
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