Created
March 27, 2021 07:38
-
-
Save hyperrealgopher/dd7332b6bd08dfce4b284d28ab5addc4 to your computer and use it in GitHub Desktop.
system-f/fp-course: Functor.hs
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
{-# LANGUAGE NoImplicitPrelude #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE InstanceSigs #-} | |
module Course.Functor where | |
import Course.Core | |
import Course.ExactlyOne | |
import Course.Optional | |
import Course.List | |
import qualified Prelude as P(fmap) | |
-- | All instances of the `Functor` type-class must satisfy two laws. These laws | |
-- are not checked by the compiler. These laws are given as: | |
-- | |
-- * The law of identity | |
-- `∀x. (id <$> x) ≅ x` | |
-- | |
-- * The law of composition | |
-- `∀f g x.(f . g <$> x) ≅ (f <$> (g <$> x))` | |
class Functor k where | |
-- Pronounced, eff-map. | |
(<$>) :: | |
(a -> b) | |
-> k a | |
-> k b | |
infixl 4 <$> | |
-- $setup | |
-- >>> :set -XOverloadedStrings | |
-- >>> import Course.Core | |
-- >>> import qualified Prelude as P(return, (>>)) | |
-- | Maps a function on the ExactlyOne functor. | |
-- | |
-- >>> (+1) <$> ExactlyOne 2 | |
-- ExactlyOne 3 | |
instance Functor ExactlyOne where | |
(<$>) :: | |
(a -> b) | |
-> ExactlyOne a | |
-> ExactlyOne b | |
f <$> (ExactlyOne a) = ExactlyOne (f a) | |
-- | Maps a function on the List functor. | |
-- | |
-- >>> (+1) <$> Nil | |
-- [] | |
-- | |
-- >>> (+1) <$> (1 :. 2 :. 3 :. Nil) | |
-- [2,3,4] | |
instance Functor List where | |
(<$>) :: | |
(a -> b) | |
-> List a | |
-> List b | |
f <$> ls = map' f Nil ls | |
where | |
map' f acc (e :. es) = map' f (f e :. acc) es | |
map' f acc Nil = reverse acc | |
-- | Maps a function on the Optional functor. | |
-- | |
-- >>> (+1) <$> Empty | |
-- Empty | |
-- | |
-- >>> (+1) <$> Full 2 | |
-- Full 3 | |
instance Functor Optional where | |
(<$>) :: | |
(a -> b) | |
-> Optional a | |
-> Optional b | |
f <$> (Full a) = Full (f a) | |
_ <$> Empty = Empty | |
-- | Maps a function on the reader ((->) t) functor. | |
-- | |
-- >>> ((+1) <$> (*2)) 8 | |
-- 17 | |
instance Functor ((->) t) where | |
(<$>) :: | |
(a -> b) | |
-> ((->) t a) | |
-> ((->) t b) | |
f1 <$> f2 = f1 . f2 | |
-- | Anonymous map. Maps a constant value on a functor. | |
-- | |
-- >>> 7 <$ (1 :. 2 :. 3 :. Nil) | |
-- [7,7,7] | |
-- | |
-- prop> \x a b c -> x <$ (a :. b :. c :. Nil) == (x :. x :. x :. Nil) | |
-- | |
-- prop> \x q -> x <$ Full q == Full x | |
(<$) :: | |
Functor k => | |
a | |
-> k b | |
-> k a | |
c <$ ls = const c <$> ls | |
-- | Anonymous map producing unit value. | |
-- | |
-- >>> void (1 :. 2 :. 3 :. Nil) | |
-- [(),(),()] | |
-- | |
-- >>> void (Full 7) | |
-- Full () | |
-- | |
-- >>> void Empty | |
-- Empty | |
-- | |
-- >>> void (+10) 5 | |
-- () | |
void :: | |
Functor k => | |
k a | |
-> k () | |
void k = (const ()) <$> k | |
----------------------- | |
-- SUPPORT LIBRARIES -- | |
----------------------- | |
-- | Maps a function on an IO program. | |
-- | |
-- >>> reverse <$> (putStr "hi" P.>> P.return ("abc" :: List Char)) | |
-- hi"cba" | |
instance Functor IO where | |
(<$>) = | |
P.fmap |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment