{-# LANGUAGE Arrows #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
module Arr where
{-
As an exercise in learning arrows, I implemented a reader arrow called EA
and a state arrow called S.
-}
import Prelude hiding ((.), id)
import Control.Category
import Control.Arrow
import qualified Data.Bifunctor as BiF
newtype EA r a b = EA { runEA :: r -> a -> b }
instance Arrow (EA r) where
arr f = EA $ const f
first (EA f) = EA $ BiF.first . f
second (EA f) = EA $ BiF.second . f
instance Category (EA r) where
id = arr id
(EA b) . (EA a) = EA $ \r -> b r . a r
class Arrow a => ArrowReader r a | a -> r where
ask :: a () r
instance ArrowReader r (EA r) where
ask = EA const
newtype S s a b = S { runS :: s -> a -> (b, s) }
evalS :: S s a b -> s -> a -> b
evalS z s a = fst $ runS z s a
execS :: S s a b -> s -> a -> s
execS z s a = snd $ runS z s a
instance Arrow (S s) where
arr f = S $ \s a -> (f a, s)
first (S f) = S $ \s (a, b) -> let (a', s') = f s a in ((a', b), s')
second (S f) = S $ \s (a, b) -> let (b', s') = f s b in ((a, b'), s')
instance Category (S s) where
id = arr id
(S b) . (S a) = S $ \s x -> let (a', s') = a s x in b s' a'
class Arrow a => ArrowState s a | a -> s where
get :: a b s
put :: a s ()
modify :: ArrowState s a => a (s -> s) ()
modify = proc f -> do
s <- get -< ()
put -< f s
instance ArrowState s (S s) where
get = S $ \s _ -> (s, s)
put = S $ \_ s -> ((), s)
Comments
0 B
|👍
/👎
0 B
|👍
/👎