Tuple

Type class

Functor

instance Functor ((,) w) where
  fmap :: (a -> b) -> (w, a) -> (w, b)
  fmap f (w, a) = (w, f a)

Applicative

instance (Monoid w, Functor ((,) w)) => Applicative ((,) w) where
  pure :: a -> (w, a)
  pure a = (mempty, a)

  (<*>) :: (w, a -> b) -> (w, a) -> (w, b)
  (w1, f) <*> (w2, v) = fmap f (w1 <> w2, v)

Monad

instance (Monoid w, Applicative ((,) w)) => Monad ((,) w) where
  (>>=) :: (w, a) -> (a -> (w, b)) -> (w, b)
  (w1, a) >>= f =
    let (w2, b) = f a
     in (w1 <> w2, b)

Memo

Writer

type Writer w a = (w, a)

runWriter :: Writer w a -> (w, a)
runWriter = id

tell :: w -> Writer w ()
tell w = (w, ())

listen :: Writer w a -> Writer w (w, a)
listen writer@(w, _) = (w, writer)

pass :: Writer w (w -> w, a) -> Writer w a
pass (w, (f, a)) = (f w, a)

listens :: (w1 -> w2) -> Writer w1 a -> Writer w1 (w2, a)
listens f (w, a) = (w, (f w, a))

-- >>> ex
-- ("lambda",("haskell-lambda",()))
ex :: Writer String (String, ())
ex = listens ("haskell-" ++) $ tell "lambda"

-- λ> mySum 10
-- ([10,9,8,7,6,5,4,3,2,1,0],55)
mySum :: Int -> Writer [Int] Int
mySum n = do
  tell [n]
  if n <= 0
    then pure n
    else do
      v <- mySum (n-1)
      pure (n + v)

Last updated