fraxl-0.1.0.0: examples/src/Main.hs
{-# 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