@@ -0,0 +1,76 @@
1+{-# LANGUAGE DeriveFunctor, FlexibleContexts, FlexibleInstances, KindSignatures, MultiParamTypeClasses,
2+ TypeApplications, TypeOperators, UndecidableInstances #-}
4+module HigherOrder (marks) where
11+data HTTP (m :: * -> *) k
14+ | Post String (String -> k)
18+instance HFunctor HTTP where
21+open' :: (Member HTTP sig, Carrier sig m) => String -> m ()
22+open' s = send (Open s (gen ()))
24+close' :: (Member HTTP sig, Carrier sig m) => m ()
25+close' = send (Close (gen ()))
27+post' :: (Member HTTP sig, Carrier sig m) => String -> m String
28+post' s = send (Post s gen)
30+get' :: (Member HTTP sig, Carrier sig m) => m String
31+get' = send (HGet gen)
33+newtype HTTPC m a = HTTPC { runHTTPC :: m a }
35+instance (Carrier sig m) => Carrier (HTTP :+: sig) (HTTPC m) where
37+ alg = algS \/ (HTTPC . alg . handlePure runHTTPC) where
40+ algS (Post s k) = k s
43+runHTTP :: (Carrier sig m) => Eff (HTTPC m) a -> m a
44+runHTTP = runHTTPC . interpret
46+oneGet :: Int -> (Int, Int)
47+oneGet n = run (runState n get)
49+countDown :: Int -> (Int,Int)
50+countDown start = run (runState start go)
51+ where go = get >>= (\n -> if n <= 0 then pure n else put (n-1) >> go)
53+countDownExc :: Int -> Either String (Int,Int)
54+countDownExc start = run $ runError (runState start go)
55+ where go = get >>= (\n -> if n <= (0 :: Int) then throwError "wat" else put (n-1) >> go)
57+prog :: (Monad m, Member HTTP sig, Carrier sig m) => m ()
58+prog = open' "cats" >> get' >> post' "cats" >> close'
60+p :: (Monad m, Member HTTP sig, Carrier sig m) => Int -> m ()
61+p count = open' "cats" >> replicateM_ count (get' >> post' "cats") >> close'
64+marks = bgroup "higher-order-effects"
66+ [ bench "get" $ whnf oneGet 0
67+ , bench "countdown" $ whnf countDown 100
69+ , bgroup "State + Error"
70+ [ bench "countdownExc" $ whnf countDownExc 10000
73+ [ bench "simple" $ whnf (run . runHTTP) prog
74+ , bench "replicated" $ whnf (run . runHTTP . p) 100000