|
1 | 1 | {-# LANGUAGE CPP #-} |
2 | 2 | {-# LANGUAGE BangPatterns #-} |
3 | 3 | {-# LANGUAGE FlexibleContexts #-} |
| 4 | +{-# LANGUAGE FlexibleInstances #-} |
4 | 5 | {-# LANGUAGE GADTs #-} |
5 | | -{-# LANGUAGE RankNTypes #-} |
| 6 | +{-# LANGUAGE LambdaCase #-} |
| 7 | +{-# LANGUAGE MultiParamTypeClasses #-} |
6 | 8 | {-# LANGUAGE RecursiveDo #-} |
7 | 9 | {-# LANGUAGE ScopedTypeVariables #-} |
| 10 | +{-# LANGUAGE TemplateHaskell #-} |
| 11 | +{-# LANGUAGE TypeApplications #-} |
| 12 | +{-# LANGUAGE TypeFamilies #-} |
8 | 13 | module Main where |
9 | 14 |
|
10 | | -import Control.Lens |
| 15 | +import Control.Lens hiding (has) |
11 | 16 | import Control.Monad |
12 | 17 | import Control.Monad.Fix |
| 18 | +import Control.Monad.IO.Class (MonadIO) |
| 19 | +import Data.Constraint.Extras |
| 20 | +import Data.Constraint.Extras.TH |
| 21 | +import Data.Constraint.Forall |
13 | 22 | import qualified Data.Dependent.Map as DMap |
14 | 23 | import Data.Dependent.Sum |
15 | 24 | import Data.Functor.Misc |
| 25 | +import Data.List (words) |
| 26 | +import Data.Map (Map) |
16 | 27 | import qualified Data.Map as M |
| 28 | +#if !MIN_VERSION_these(4,11,0) |
| 29 | +import Data.Semigroup ((<>)) |
| 30 | +#endif |
| 31 | +import Data.Text (Text) |
17 | 32 | import Data.These |
| 33 | +import Text.Read (readMaybe) |
18 | 34 |
|
19 | 35 | #if defined(MIN_VERSION_these_lens) || (MIN_VERSION_these(0,8,0) && !MIN_VERSION_these(0,9,0)) |
20 | 36 | import Data.These.Lens |
@@ -49,12 +65,19 @@ main = do |
49 | 65 | print os5 |
50 | 66 | os6 <- runApp' (unwrapApp delayedPulse) [Just ()] |
51 | 67 | print os6 |
| 68 | + os7 <- runApp' testMatchRequestsWithResponses [ Just $ TestRequest_Increment 1 ] |
| 69 | + print os7 |
| 70 | + os8 <- runApp' testMatchRequestsWithResponses [ Just $ TestRequest_Reverse "yoyo" ] |
| 71 | + print os8 |
52 | 72 | let ![[Just [1,2,3,4,5,6,7,8,9,10]]] = os1 -- The order is reversed here: see the documentation for 'runRequesterT' |
53 | 73 | let ![[Just [9,7,5,3,1]],[Nothing,Nothing],[Just [10,8,6,4,2]],[Just [10,8,6,4,2],Nothing]] = os2 |
54 | 74 | let ![[Nothing, Just [2]]] = os3 |
55 | 75 | let ![[Nothing, Just [2]]] = os4 |
56 | 76 | let ![[Nothing, Just [1, 2]]] = os5 |
57 | 77 | -- let ![[Nothing, Nothing]] = os6 -- TODO re-enable this test after issue #233 has been resolved |
| 78 | + let !(Just [(1,"2")]) = M.toList <$> head (head os7) |
| 79 | + let !(Just [(1,"oyoy")]) = M.toList <$> head (head os8) |
| 80 | + |
58 | 81 | return () |
59 | 82 |
|
60 | 83 | unwrapRequest :: DSum tag RequestInt -> Int |
@@ -172,3 +195,41 @@ delayedPulse pulse = void $ flip runWithReplace (pure () <$ pulse) $ do |
172 | 195 | -- This has the effect of delaying pulse' from pulse |
173 | 196 | (_, pulse') <- runWithReplace (pure ()) $ pure (RequestInt 1) <$ pulse |
174 | 197 | requestingIdentity pulse' |
| 198 | + |
| 199 | +data TestRequest a where |
| 200 | + TestRequest_Reverse :: String -> TestRequest String |
| 201 | + TestRequest_Increment :: Int -> TestRequest Int |
| 202 | + |
| 203 | +testMatchRequestsWithResponses |
| 204 | + :: forall m t req a |
| 205 | + . ( MonadFix m |
| 206 | + , MonadHold t m |
| 207 | + , Reflex t |
| 208 | + , PerformEvent t m |
| 209 | + , MonadIO (Performable m) |
| 210 | + , ForallF Show req |
| 211 | + , Has Read req |
| 212 | + ) |
| 213 | + => Event t (req a) -> m (Event t (Map Int String)) |
| 214 | +testMatchRequestsWithResponses pulse = mdo |
| 215 | + (_, requests) <- runRequesterT (requesting pulse) responses |
| 216 | + let rawResponses = M.map (\v -> |
| 217 | + case words v of |
| 218 | + ["reverse", str] -> reverse str |
| 219 | + ["increment", i] -> show $ succ $ (read i :: Int) |
| 220 | + ) <$> rawRequestMap |
| 221 | + (rawRequestMap, responses) <- matchResponsesWithRequests reqEncoder requests (head . M.toList <$> rawResponses) |
| 222 | + pure rawResponses |
| 223 | + where |
| 224 | + reqEncoder :: forall a. req a -> (String, String -> Maybe a) |
| 225 | + reqEncoder r = |
| 226 | + ( whichever @Show @req @a $ show r |
| 227 | + , \x -> has @Read r $ readMaybe x |
| 228 | + ) |
| 229 | + |
| 230 | +deriveArgDict ''TestRequest |
| 231 | + |
| 232 | +instance Show (TestRequest a) where |
| 233 | + show = \case |
| 234 | + TestRequest_Reverse str -> "reverse " <> str |
| 235 | + TestRequest_Increment i -> "increment " <> show i |
0 commit comments