@@ -0,0 +1,53 @@
1+{-# LANGUAGE TypeOperators, FlexibleInstances, KindSignatures, MultiParamTypeClasses, DeriveFunctor, UndecidableInstances, GeneralizedNewtypeDeriving #-}
3+module Fused.HTTP where
6+import Control.Effect.Sum
7+import Control.Effect.Carrier
9+import Control.Monad.IO.Class
11+newtype HttpC m a = HttpC { runHttpC :: m a }
12+ deriving (Applicative, Functor, Monad, MonadIO)
14+data HTTP (m :: * -> *) k
17+ | Post String (String -> k)
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)
27+instance HFunctor HTTP where
30+open' :: String -> HttpM ()
31+open' s = send (Open s (pure ()))
34+close' = send (Close (pure ()))
36+post' :: String -> HttpM String
37+post' s = send (Post s pure)
40+get' = send (HGet pure)
42+type HttpM = HttpC (LiftC IO)
44+instance (Effect sig, Carrier sig m) => Carrier (HTTP :+: sig) (HttpC m) where
45+ eff (L act) = case act of
48+ Post s k -> k ("posted " <> s)
50+ eff (R other) = HttpC (eff (handleCoercible other))
52+runHttp :: HttpM a -> IO a
53+runHttp = runM . runHttpC