Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.67 KB | None | 0 0
  1. module Main where
  2.  
  3. import GHC.Generics
  4. import Control.Monad.Writer
  5.  
  6. data T
  7. data G
  8.  
  9. data Group t a where
  10. Describe :: String -> [Group t a] -> Group G a
  11. It :: String -> [Group T a] -> Group G a
  12. Effort :: Float -> Group T a
  13.  
  14. deriving instance Functor (Group x)
  15. deriving instance Show a => Show (Group x a)
  16.  
  17. type Spec m a = WriterT [Group G a] m ()
  18. type TaskSpec m a = WriterT [Group T a] m ()
  19.  
  20. class (Monad m, Applicative f) => MonadSpec m f where
  21. it :: String -> TaskSpec m (f a) -> Spec m (f a)
  22.  
  23. it' :: String -> Spec m (f a)
  24. it' s = it s (return ())
  25.  
  26. describe :: String -> Spec m (f a) -> Spec m (f a)
  27. effort :: Float -> TaskSpec m (f a)
  28.  
  29. newtype Collector m a = Collector { unCollector :: m a }
  30. deriving ( Functor
  31. , Applicative
  32. , Monad
  33. , MonadIO
  34. )
  35.  
  36. instance (Monad m, MonadIO m) => MonadSpec (Collector m) IO where
  37.  
  38. it name attrSpec = do
  39. tell [It name []]
  40.  
  41. describe name spec = do
  42. sub <- lift $ execWriterT spec
  43. tell [Describe name sub]
  44.  
  45. effort f = tell [Effort f]
  46.  
  47. collect :: Monad m => Spec (Collector m) (m (m a)) -> m [Group G (m a)]
  48. collect spec = do
  49. groups <- unCollector $ execWriterT spec
  50. return (map (fmap join) groups)
  51.  
  52. run :: MonadIO m => Spec (Collector m) (m (m ())) -> m ()
  53. run spec = do
  54. groups <- collect spec
  55. mapM_ (go 0) groups
  56. where
  57. go _ (Describe s gs) = liftIO $ print s >> mapM_ (go 0) gs
  58. go _ _ = error "wut"
  59.  
  60. mySpec :: MonadSpec m IO => Spec m (IO (IO ()))
  61. mySpec = describe "module 1" $ do
  62. it' "shit1"
  63. describe "feature A" $ do
  64. it "works!" $ effort 2.0
  65.  
  66. main :: IO ()
  67. main = run mySpec --putStrLn "Hello, Haskell!"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement