{-# OPTIONS_GHC -Werror #-} {-# LANGUAGE TypeOperators, GADTs, DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE Safe #-} -- | Example usage of "Control.Eff" module Control.Eff.Example where import Control.Eff import Control.Eff.Exception import Control.Eff.State.Lazy import Control.Eff.Writer.Lazy -- {{{ TooBig -- | The datatype for the example from the paper. See the tests for the example newtype TooBig = TooBig Int deriving (Eq, Show) -- | specialization to tell the type of the exception runErrBig :: Eff (Exc TooBig ': r) a -> Eff r (Either TooBig a) runErrBig = runExc -- }}} -- | Write the elements of a list of numbers, in order. writeAll :: (Member (Writer a) e) => [a] -> Eff e () writeAll = mapM_ tell -- | Add a list of numbers to the current state. sumAll :: (Num a, Member (State a) e) => [a] -> Eff e () sumAll = mapM_ (modify . (+)) -- | Write a list of numbers and add them to the current state. writeAndAdd :: (Member (Writer a) e, Member (State a) e, Num a) => [a] -> Eff e () writeAndAdd l = do writeAll l sumAll l -- | Sum a list of numbers. sumEff :: (Num a) => [a] -> a sumEff l = let ((), s) = run $ runState (sumAll l) 0 in s -- | Safely get the last element of a list. -- Nothing for empty lists; Just the last element otherwise. lastEff :: [a] -> Maybe a lastEff l = let ((), a) = run $ runLastWriter $ writeAll l in a -- | Get the last element and sum of a list lastAndSum :: (Num a) => [a] -> (Maybe a, a) lastAndSum l = let (((), total), lst) = run $ runLastWriter $ runState (writeAndAdd l) 0 in (lst, total) -- Example by Oscar Key data Move x where Move :: Move () handUp :: Eff (Move ': r) a -> Eff r a handUp (Val x) = return x handUp (E u q) = case decomp u of Right Move -> handDown $ qApp q () -- Relay other requests Left u0 -> E u0 ident >>= handUp . qApp q handDown :: Eff (Move ': r) a -> Eff r a handDown (Val x) = return x handDown (E u q) = case decomp u of Right Move -> handUp $ qApp q () -- Relay other requests Left u0 -> E u0 ident >>= handDown . qApp q