Skip to content

Commit 91f857a

Browse files
committed
Examples
1 parent 9c127ea commit 91f857a

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
module Bluefin.Examples.FunctorCoroutine where
2+
3+
import Bluefin.Eff (Eff, runEff, (:&), (:>))
4+
import Bluefin.FunctorCoroutine
5+
import Bluefin.HandleReader (HandleReader, askHandle, runHandleReader)
6+
import Bluefin.IO (IOE, effIO)
7+
import Data.Kind (Type)
8+
9+
data FileSystem :: Effect where
10+
ReadFile :: FilePath -> FileSystem m String
11+
WriteFile :: FilePath -> String -> FileSystem m ()
12+
13+
readFile ::
14+
(e1 :> es) => Send FileSystem e1 -> FilePath -> Eff es String
15+
readFile fc path = send fc (ReadFile path)
16+
17+
writeFile ::
18+
(e1 :> es) =>
19+
Send FileSystem e1 ->
20+
FilePath ->
21+
String ->
22+
Eff es ()
23+
writeFile fc path content = send fc (WriteFile path content)
24+
25+
type Effect = (Type -> Type) -> Type -> Type
26+
27+
data E :: Effect where
28+
Op1 :: E m ()
29+
Op2 :: E m ()
30+
Op3 :: E m ()
31+
32+
instance MFunctor E where
33+
mfmap _ = \case
34+
Op1 -> Op1
35+
Op2 -> Op2
36+
Op3 -> Op3
37+
38+
runE ::
39+
(e1 :> es) =>
40+
IOE e1 ->
41+
(forall e. Send E e -> Eff (e :& es) r) ->
42+
Eff es r
43+
runE io = interpret $ \case
44+
Op1 -> effIO io (putStrLn "op1")
45+
Op2 -> effIO io (putStrLn "op2")
46+
Op3 -> error "Op3 not implemented"
47+
48+
augmentOp2Interpret ::
49+
(e1 :> es, e2 :> es) =>
50+
Send E e1 ->
51+
IOE e2 ->
52+
(forall e. Send E e -> Eff (e :& es) r) ->
53+
Eff es r
54+
augmentOp2Interpret fc io = interpret $ \case
55+
Op2 -> effIO io (putStrLn "augmented op2") >> send fc Op2
56+
op -> passthrough fc op
57+
58+
augmentOp2Interpose ::
59+
(e1 :> es, e2 :> es) =>
60+
IOE e2 ->
61+
HandleReader (Send E) e1 ->
62+
Eff es r ->
63+
Eff es r
64+
augmentOp2Interpose io = interpose $ \fc -> \case
65+
Op2 -> effIO io (putStrLn "augmented op2") >> send fc Op2
66+
op -> passthrough fc op
67+
68+
-- ghci> example
69+
-- op1
70+
-- augmented op2
71+
-- op2
72+
example :: IO ()
73+
example = runEff $ \io -> do
74+
effIO io (putStrLn "interpret")
75+
let action fc = send fc Op1 >> send fc Op2
76+
runE io $ \fc -> augmentOp2Interpret fc io $ \fc' -> action fc'
77+
78+
effIO io (putStrLn "interpose")
79+
let actionHandleReader hr = do
80+
fc <- askHandle hr
81+
action fc
82+
runE io $ \fc -> runHandleReader fc $ \hr -> do
83+
augmentOp2Interpose io hr $ actionHandleReader hr

bluefin-internal/src/Bluefin/Internal.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,7 @@ mapHandleReader = case coerceH of Coercion -> coerce
14401440
coerceH :: Coercion (h e) (h es)
14411441
coerceH = unsafeCoerce (Coercion :: Coercion (h e) (h e))
14421442

1443+
-- Maybe we should make a verison of this that takes @h e -> h es@.
14431444
localHandle ::
14441445
(e :> es, Handle h) =>
14451446
HandleReader h e ->

bluefin-internal/src/Bluefin/Internal/FunctorCoroutine.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ module Bluefin.Internal.FunctorCoroutine where
33
import Bluefin.Internal
44
( Eff,
55
Handle (mapHandle),
6+
HandleReader,
7+
localHandle,
68
useImpl,
79
useImplIn,
810
useImplUnder,
@@ -52,3 +54,12 @@ passthrough ::
5254
-- | ͘
5355
Eff es r
5456
passthrough fc = send fc . mfmap useImpl
57+
58+
interpose ::
59+
(e1 :> es) =>
60+
(Send f es -> EffectHandler f es) ->
61+
HandleReader (Send f) e1 ->
62+
Eff es r ->
63+
-- | ͘
64+
Eff es r
65+
interpose h hr = localHandle hr (\fcOrig -> MkSend (h fcOrig))

0 commit comments

Comments
 (0)