-
Notifications
You must be signed in to change notification settings - Fork 10
/
Main.hs
97 lines (81 loc) · 2.61 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
module Main where
import Control.Concurrent
import Control.Monad.Fraxl
import Control.Monad.IO.Class
import Control.Monad.State
main :: IO ()
main = do
let fraxl = (++) <$> myFraxl <*> myFraxl
(strs, reqs) <- runStateT
(evalCachedFraxl (fetchMySource |:| fetchMySource2 |:| fetchNil) fraxl)
0
putStrLn ("Number of MySource2 requests made: " ++ show reqs)
print $ length strs
print strs
myFraxl :: (MonadFraxl MySource m, MonadFraxl MySource2 m) => m [String]
myFraxl = replicate <$> myInt2 <*> myString
data MySource a where
MyString :: MySource String
MyInt :: MySource Int
instance GEq MySource where
MyString `geq` MyString = Just Refl
MyInt `geq` MyInt = Just Refl
_ `geq` _ = Nothing
instance GCompare MySource where
MyString `gcompare` MyString = GEQ
MyString `gcompare` MyInt = GLT
MyInt `gcompare` MyString = GGT
MyInt `gcompare` MyInt = GEQ
fetchMySource :: MonadIO m => Fetch MySource m a
fetchMySource = simpleAsyncFetch simpleFetch
where
simpleFetch :: MySource a -> IO a
simpleFetch MyString = do
putStrLn "Sleeping String!"
threadDelay 1000000
return "String!"
simpleFetch MyInt = do
putStrLn "Sleeping Int!"
threadDelay 1000000
return 10
myString :: MonadFraxl MySource m => m String
myString = dataFetch MyString
myInt :: MonadFraxl MySource m => m Int
myInt = dataFetch MyInt
data MySource2 a where
MyString2 :: MySource2 String
MyInt2 :: MySource2 Int
instance GEq MySource2 where
MyString2 `geq` MyString2 = Just Refl
MyInt2 `geq` MyInt2 = Just Refl
_ `geq` _ = Nothing
instance GCompare MySource2 where
MyString2 `gcompare` MyString2 = GEQ
MyString2 `gcompare` MyInt2 = GLT
MyInt2 `gcompare` MyString2 = GGT
MyInt2 `gcompare` MyInt2 = GEQ
fetchMySource2 :: (MonadIO m, MonadState Int m) => Fetch MySource2 m a
fetchMySource2 a = modify (+ clength a) >> simpleAsyncFetch simpleFetch a
where
clength :: ASeq f r -> Int
clength ANil = 0
clength (ACons _ rs) = 1 + clength rs
simpleFetch :: MySource2 a -> IO a
simpleFetch MyString2 = do
putStrLn "Sleeping String2!"
threadDelay 1000000
return "String!"
simpleFetch MyInt2 = do
putStrLn "Sleeping Int2!"
threadDelay 1000000
return 10
myString2 :: MonadFraxl MySource2 m => m String
myString2 = dataFetch MyString2
myInt2 :: MonadFraxl MySource2 m => m Int
myInt2 = dataFetch MyInt2