Skip to content

Instantly share code, notes, and snippets.

@homam
Created May 3, 2018 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save homam/a083dc75b819ee55367f3c7390c829bc to your computer and use it in GitHub Desktop.
Save homam/a083dc75b819ee55367f3c7390c829bc to your computer and use it in GitHub Desktop.
module Counter where
import Prelude
import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Eff.Console (logShow)
import Control.Monad.RWS.Trans (class MonadTrans)
import Control.Monad.State (StateT, get, put, runStateT)
import Control.Monad.Trans.Class (lift)
import Data.Tuple (Tuple)
class Monad m <= MonadCounter m where
increment :: m Int
current :: m Int
newtype CounterT m a = CounterT (StateT Int m a)
runCounterT :: forall m a. CounterT m a -> Int -> m (Tuple a Int)
runCounterT (CounterT c) = runStateT c
derive newtype instance functorCounterT :: Functor m => Functor (CounterT m)
derive newtype instance monadCounterT :: Monad m => Monad (CounterT m)
derive newtype instance applicativeCounterT :: Monad m => Applicative (CounterT m)
derive newtype instance applyCounterT :: Monad m => Apply (CounterT m)
instance monadTransCounterT :: MonadTrans CounterT where
lift = CounterT <<< lift
instance monadEffCounterT :: MonadEff eff m => MonadEff eff (CounterT m) where
liftEff = lift <<< liftEff
-- Actual CounterT implementation:
instance monadCounterCounterT :: Monad m => MonadCounter (CounterT m) where
increment = CounterT $ do
c <- get
let n = c + 1
put n
pure n
current = CounterT get
---
-- simpleApp should work for any instance of MonadCounter
myApp :: forall m. Monad m => MonadCounter m => m Int
myApp = increment
---
newtype SimpleApp m a = SimpleApp (CounterT m a)
runSimpleApp :: ∀ a m. SimpleApp m a → Int → m (Tuple a Int)
runSimpleApp (SimpleApp c) = runCounterT c
derive newtype instance functorSimpleApp :: Functor m => Functor (SimpleApp m)
derive newtype instance monadSimpleApp :: Monad m => Monad (SimpleApp m)
derive newtype instance applySimpleApp :: Monad m => Apply (SimpleApp m)
derive newtype instance applicativeSimpleApp :: Monad m => Applicative (SimpleApp m)
derive newtype instance monadCounterSimpleApp :: MonadCounter m => MonadCounter (SimpleApp m)
derive newtype instance monadEffSimpleApp :: MonadEff eff m => MonadEff eff (SimpleApp m)
-- main :: forall e. Eff
-- ( console :: CONSOLE
-- | e
-- )
-- Unit
-- main = runSimpleApp myApp 12 >>= logShow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment