Quick actions

cmd+k|ctrl+k

Navigation

Languages

Monad Bind, Associativity Matters

Snippet info

Language

Haskell

Visibility

public

Author

homam

Created

2016-09-26T19:39:52Z

Updated

2016-09-27T07:43:07Z

{-# LANGUAGE DeriveFunctor #-}

import Debug.Trace (trace)
import Control.Monad ((>=>))

data Tree a = Node (Tree a) (Tree a) | Leaf a deriving Functor

instance Applicative Tree where
  pure = Leaf
  Leaf f <*> Leaf a = Leaf $ f a
  Leaf f <*> Node a b =  Node (f <$> a) (f <$> b)
  Node f g <*> leaf@(Leaf x) = Node (f <*> leaf) (g <*> leaf)
  Node f g <*> Node a b = Node (f <*> a) (g <*> b)

instance Monad Tree where
  return = pure
  (>>=) = (<-/)

(<-/) :: Tree a -> (a -> Tree b) -> Tree b
(Leaf a) <-/ f = f a
Node l r <-/ f = trace "<-/" (Node (l <-/ f) (r <-/ f))


instance Show a => Show (Tree a) where
  show (Leaf a) = "Leaf " ++ show a
  show (Node l r) = "Node (" ++ show l ++ ") (" ++ show r ++ ")"

x :: Tree Int
x =
  Node
    (Node
      (Leaf 9)
      (Node (Leaf 8) (Leaf 7))
    )
    (Leaf 2)

f x = Leaf $ x * 5
g x = Leaf $ x + 1

main = do

  -- time: |x| + |(x >>= f)| steps
  print $ (x >>= f) >>= g

  trace (replicate 10 '-') (return ())

  -- time: |x >>= f| steps
  print $ x >>= (\x -> f x >>= g)

  trace (replicate 10 '-') (return ())

  print $ x >>= (f >=> g)
INFO