@@ -0,0 +1,53 @@
1+{-# LANGUAGE TypeOperators, FlexibleInstances, KindSignatures, MultiParamTypeClasses, DeriveFunctor, UndecidableInstances, GeneralizedNewtypeDeriving #-}
2+
3+module Fused.HTTP where
4+
5+import Control.Effect
6+import Control.Effect.Sum
7+import Control.Effect.Carrier
8+import Data.Coerce
9+import Control.Monad.IO.Class
10+
11+newtype HttpC m a = HttpC { runHttpC :: m a }
12+ deriving (Applicative, Functor, Monad, MonadIO)
13+
14+data HTTP (m :: * -> *) k
15+ = Open String k
16+ | Close k
17+ | Post String (String -> k)
18+ | HGet (String -> k)
19+ deriving Functor
20+
21+instance Effect HTTP where
22+ handle state handler (Open s k) = Open s (handler . (<$ state) $ k)
23+ handle state handler (Close k) = Close (handler . (<$ state) $ k)
24+ handle state handler (Post s k) = Post s (handler . (<$ state) . k)
25+ handle state handler (HGet k) = HGet (handler . (<$ state) . k)
26+
27+instance HFunctor HTTP where
28+ hmap _ = coerce
29+
30+open' :: String -> HttpM ()
31+open' s = send (Open s (pure ()))
32+
33+close' :: HttpM ()
34+close' = send (Close (pure ()))
35+
36+post' :: String -> HttpM String
37+post' s = send (Post s pure)
38+
39+get' :: HttpM String
40+get' = send (HGet pure)
41+
42+type HttpM = HttpC (LiftC IO)
43+
44+instance (Effect sig, Carrier sig m) => Carrier (HTTP :+: sig) (HttpC m) where
45+ eff (L act) = case act of
46+ Open _ k -> k
47+ Close k -> k
48+ Post s k -> k ("posted " <> s)
49+ HGet k -> k "lmao"
50+ eff (R other) = HttpC (eff (handleCoercible other))
51+
52+runHttp :: HttpM a -> IO a
53+runHttp = runM . runHttpC