Skip to content

Commit

Permalink
Some WIP material.
Browse files Browse the repository at this point in the history
  • Loading branch information
athas committed Oct 10, 2024
1 parent e07c71f commit 7d6b7fe
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 3 deletions.
6 changes: 3 additions & 3 deletions haskell/Week2/ReaderState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,20 @@ newtype State s a = State (s -> (a, s))
-- ANCHOR_END: State

-- ANCHOR: Functor_State
instance Functor (State env) where
instance Functor (State s) where
fmap = liftM

-- ANCHOR_END: Functor_State

-- ANCHOR: Applicative_State
instance Applicative (State env) where
instance Applicative (State s) where
pure x = State $ \state -> (x, state)
(<*>) = ap

-- ANCHOR_END: Applicative_State

-- ANCHOR: Monad_State
instance Monad (State env) where
instance Monad (State s) where
State m >>= f = State $ \state ->
let (x, state') = m state
State f' = f x
Expand Down
102 changes: 102 additions & 0 deletions haskell/Week7/FreeConcurrency.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{-# LANGUAGE ExistentialQuantification #-}

module Week6.FreeConcurrency where

import Control.Concurrent (Chan, forkIO, newChan, readChan, writeChan)
import Control.Monad (ap, liftM)
import Week2.ReaderState (State, get, put, runState)

data Free e a
= Pure a
| Free (e (Free e a))

instance (Functor e) => Functor (Free e) where
fmap = liftM

instance (Functor e) => Applicative (Free e) where
pure = Pure
(<*>) = ap

instance (Functor e) => Monad (Free e) where
Pure x >>= f = f x
Free g >>= f = Free $ h <$> g
where
h x = x >>= f

type CC chan a = Free (CCOp chan) a

data CCOp chan a
= CCPrint String a
| CCFork (CC chan ()) a
| forall msg. CCNewChan (chan msg -> a)
| forall msg. CCSend (chan msg) msg a
| forall msg. CCReceive (chan msg) (msg -> a)

instance Functor (CCOp chan) where
fmap f (CCPrint s c) = CCPrint s (f c)
fmap f (CCFork m c) = CCFork m (f c)
fmap f (CCNewChan c) = CCNewChan $ f . c
fmap f (CCSend chan msg c) = CCSend chan msg $ f c
fmap f (CCReceive chan c) = CCReceive chan $ f . c

ccNewChan :: CC chan (chan msg)
ccNewChan = Free $ CCNewChan pure

ccFork :: CC chan () -> CC chan ()
ccFork m = Free $ CCFork m $ pure ()

ccPrint :: String -> CC chan ()
ccPrint s = Free $ CCPrint s $ pure ()

ccSend :: chan msg -> msg -> CC chan ()
ccSend chan msg = Free $ CCSend chan msg $ pure ()

ccReceive :: chan msg -> CC chan msg
ccReceive chan = Free $ CCReceive chan pure

interpCCIO :: CC Chan a -> IO a
interpCCIO (Pure x) =
pure x
interpCCIO (Free (CCPrint s c)) = do
putStrLn s
interpCCIO c
interpCCIO (Free (CCFork m c)) = do
_ <- forkIO $ interpCCIO m
interpCCIO c
interpCCIO (Free (CCNewChan c)) = do
chan <- newChan
interpCCIO $ c chan
interpCCIO (Free (CCSend chan msg c)) = do
writeChan chan msg
interpCCIO c
interpCCIO (Free (CCReceive chan c)) = do
msg <- readChan chan
interpCCIO $ c msg

data CCState = CCState {ccCounter :: Int}

interpCCPure :: CC Chan a -> a
interpCCPure orig = fst $ runState initial_state (interp orig)
where
initial_state = CCState {ccCounter = 0}
interp = undefined

carousel :: CC chan Int
carousel = do
chan_0 <- ccNewChan
chan_1 <- ccNewChan
chan_2 <- ccNewChan
chan_3 <- ccNewChan
chan_4 <- ccNewChan
let passOn from to = do
y <- ccReceive from
ccSend to $ y + 1
ccFork $ passOn chan_0 chan_1
ccFork $ passOn chan_1 chan_2
ccFork $ passOn chan_2 chan_3
ccFork $ passOn chan_3 chan_4
ccSend chan_0 0
ccReceive chan_4

try :: IO ()
try = print =<< interpCCIO carousel

0 comments on commit 7d6b7fe

Please sign in to comment.