{-# LANGUAGE DefaultSignatures #-}
module Clean.Classes where

import Clean.Core

class Functor f where
  map :: (a -> b) -> f a -> f b
  default map :: Applicative f => (a -> b) -> f a -> f b
  map f = (<*>) (pure f)
class (Unit f, Functor f) => Applicative f where
  (<*>) :: f (a -> b) -> f a -> f b
  default (<*>) :: Monad f => f (a -> b) -> f a -> f b
  f <*> x = f >>= \f -> x >>= \x -> pure (f x)
class Applicative m => Monad m where
  join :: m (m a) -> m a
  join m = m >>= id
  (>>=) :: m a -> (a -> m b) -> m b
  ma >>= k = join (map k ma)
infixl 1 >>=