@@ -1,18 +1,26 @@
1{-# LANGUAGE TypeFamilies #-}
1{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE EmptyDataDecls #-}
3{-# LANGUAGE EmptyDataDecls #-}
4+{-# LANGUAGE TemplateHaskell #-}
5+{-# LANGUAGE ConstraintKinds #-}
4module Main where
6module Main where
8+import Control.Ether.TH
6import Control.Monad.Ether.Reader
9import Control.Monad.Ether.Reader
8import Data.Proxy
11import Data.Proxy
9import Data.Functor.Identity
12import Data.Functor.Identity
10−import Control.Ether.Core
12import Test.Tasty
14import Test.Tasty
13import Test.Tasty.QuickCheck
15import Test.Tasty.QuickCheck
14import Test.QuickCheck.Function
16import Test.QuickCheck.Function
18+etherealReader "AmountTag" "runAmountT" "askAmount" ''Int
19+type MonadAmount = MonadEtherReader AmountTag
21+etherealReader "CountTag" "runCountT" "askCount" ''Integer
22+type MonadCount = MonadEtherReader CountTag
16main :: IO ()
24main :: IO ()
17main = defaultMain suite
25main = defaultMain suite
@@ -29,42 +37,24 @@ layeredLocalLeft, layeredLocalRight
30layeredLocalLeft k f a1 a2 = property (direct == indirect)
38layeredLocalLeft k f a1 a2 = property (direct == indirect)
32− run = runIdentity . flip runAmountT a1 . flip runAmount2T a2
40+ run = runIdentity . flip runAmountT a1 . flip runCountT a2
33 direct = apply k (fromIntegral a1, apply f a2)
41 direct = apply k (fromIntegral a1, apply f a2)
34 indirect = run $ layeredLocalCore (apply f) (\n m -> apply k (fromIntegral n, m))
42 indirect = run $ layeredLocalCore (apply f) (\n m -> apply k (fromIntegral n, m))
36layeredLocalRight k f a1 a2 = property (direct == indirect)
44layeredLocalRight k f a1 a2 = property (direct == indirect)
38− run = runIdentity . flip runAmount2T a2 . flip runAmountT a1
46+ run = runIdentity . flip runCountT a2 . flip runAmountT a1
39 direct = apply k (fromIntegral a1, apply f a2)
47 direct = apply k (fromIntegral a1, apply f a2)
40 indirect = run $ layeredLocalCore (apply f) (\n m -> apply k (fromIntegral n, m))
48 indirect = run $ layeredLocalCore (apply f) (\n m -> apply k (fromIntegral n, m))
42layeredLocalCore
50layeredLocalCore
43− :: (MonadEtherReader AmountTag m, MonadEtherReader Amount2Tag m)
51+ :: (MonadAmount m, MonadCount m)
44 => (Integer -> Integer) -> (Int -> Integer -> a) -> m a
52 => (Integer -> Integer) -> (Int -> Integer -> a) -> m a
45layeredLocalCore f g = do
53layeredLocalCore f g = do
46 n <- askAmount
54 n <- askAmount
47− m <- etherLocal (Proxy :: Proxy Amount2Tag) f askAmount2
55+ m <- etherLocal (Proxy :: Proxy CountTag) f askCount
48 return (g n m)
56 return (g n m)
51−type instance EtherData AmountTag = Int
53−runAmountT :: EtherReaderT AmountTag m a -> EtherData AmountTag -> m a
54−runAmountT = runEtherReaderT (Proxy :: Proxy AmountTag)
56−askAmount :: MonadEtherReader AmountTag m => m (EtherData AmountTag)
57−askAmount = etherAsk (Proxy :: Proxy AmountTag)
60−type instance EtherData Amount2Tag = Integer
62−runAmount2T :: EtherReaderT Amount2Tag m a -> EtherData Amount2Tag -> m a
63−runAmount2T = runEtherReaderT (Proxy :: Proxy Amount2Tag)
65−askAmount2 :: MonadEtherReader Amount2Tag m => m (EtherData Amount2Tag)
66−askAmount2 = etherAsk (Proxy :: Proxy Amount2Tag)
68-- this should not compile
58-- this should not compile
69z :: IO Int
59z :: IO Int
70z = runAmountT (runAmountT (runAmountT askAmount 20) 10) 5
60z = runAmountT (runAmountT (runAmountT askAmount 20) 10) 5