Marcelo Camargo

Systems analyst, translator & programming languages researcher

Monads, monoids and functors

marcelocamargo@linuxmail.org

github.com/haskellcamargo

Index

1. Computations may fail

2. Concepts and definitions

3. Using monads to solve problems

4. Conclusion

1. Computations may fail

var head = function(list) {
  return list[0];
}
head :: [a] -> a
head (x:_) = x
main :: IO ()
main = print $ head []
NULL!?
Every time you returns null, a capybara dies

Ah, but, what can go wrong?

─ I/O operations

─ Non-exhaustive patterns

─ HTTP requests

2. Concepts and definitions

A MONAD IS JUST A MONOID

IN THE CATEGORY OF THE ENDOFUNCTORS

class Monad m where
  return   :: a -> m a
  (>>=)    :: m a -> (a -> m b) -> m b
  (>>)     :: m a -> m b -> m b
  (m >> n) :: m >>= \_ -> n

Monoid

─ Algebraic structure

─ Fulfills identity principle (no-op)

0 + 7 == 7 + 0 == 7
[] ++ [1, 2, 3] == [1, 2, 3] ++ [] == [1, 2, 3]
{} union {apple} == {apple} union {} == {apple}

─ A set of objects and a way to join them

Functor

─ Work on a structure without touching it

─ Implements fmap

class Functor f where
  fmap :: (a -> b) -> f a -> f b

-- Should obey
fmap id      = id
fmap (p . q) = (fmap p) . (fmap q)

─ Category mapping

Endofunctor

─ Functor mapping A -> A

─ Also implements fmap

µ :: Monad m => m (m a) -> m a

─ So, monads are monoids and they fit in the category of the endofunctors

Monads?

Monads!

data Maybe = Just a | Nothing
> fmap (+3) (Just 2)
Just 5
instance Functor Maybe where
  fmap func (Just val) = Just (func val)
  fmap func Nothing = Nothing

fmap of function to function <$>

>>=

Thank you, Aditya Bhargava!

3. Using monads to solve problems

module IOExample where

-- Using binding, applying a monad
-- IO String and returning a monad IO ()
main :: IO ()
main = getLine >>= putStrLn

-- Using do-notation to simulate
-- imperative programming
main' :: IO ()
main' = do
  line <- getLine
  putStrLn line
module MaybeExample where
import Data.Maybe (fromJust)

-- Safe definition of
head' :: [a] -> Maybe a
head' [] = Nothing
head' (x:_) = Just x

failure :: [String]
failure = []

success :: [String]
success = ["eita"]

-- Safe and monadic usage of head
nop = return (head' failure) >>= putStrLn . show
op  = return (head' success) >>= putStrLn . show
// findUser :: Integer -> Maybe { name :: String }
var findUser = function(id) { ... }

var handleUser = function(id) {
  findUser(id)
    .bind(user => {
        console.log("Welcome, " + user + "!");
    });
}
// findUser :: Integer -> Maybe { name :: String }
var findUser = function(id) { ... }

var handleUser = function(id) {
  var user = findUser(id).def("Visitor");
  console.log("Welcome, " + user + "!");
}

4. Conclusion

1. Computations may fail

2. Monads hold error-prone states

4. Monads are love <3

[EN] Monads, monoids and functors

By Marcelo Camargo

[EN] Monads, monoids and functors

  • 1,675