Skip to content

Instantly share code, notes, and snippets.

@louispan
Last active April 15, 2018 08:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louispan/71aca6b4ba4118981a176c582fa02070 to your computer and use it in GitHub Desktop.
Save louispan/71aca6b4ba4118981a176c582fa02070 to your computer and use it in GitHub Desktop.
Example of a reader & state of Many items
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
module Main where
import Control.Lens
import Control.Monad.Reader
import Control.Monad.State
import Data.Diverse.Lens
import Data.Semigroup
import Data.Has
-- Reader of multiple items using Data.Diverse.Lens
foo :: (MonadReader r m, HasItem' Int r, HasItem' String r) => m (Int, String)
foo = do
i <- view (item' @Int) -- explicitly specify type
s <- view item' -- type can also be inferred
pure (i + 10, s <> "bar")
-- Reader of multiple items using Data.Has
foo2 :: (MonadReader r m, Has Int r, Has String r) => m (Int, String)
foo2 = do
i <- view (hasLens @Int) -- explicitly specify type
s <- view hasLens -- type can also be inferred
pure (i + 10, s <> "bar")
-- State of multiple items using Data.Diverse.Lens
bar :: (MonadState s m, HasItem' Int s, HasItem' String s) => m ()
bar = do
(item' @Int) %= (+10) -- explicitly specify type
item' %= (<> "bar") -- type can also be inferred
pure ()
-- State of multiple items using Data.Has
bar2 :: (MonadState s m, Has Int s, Has String s) => m ()
bar2 = do
(hasLens @Int) %= (+10) -- explicitly specify type
hasLens %= (<> "bar") -- type can also be inferred
pure ()
main :: IO ()
main = do
-- Using Data.Diverse
-- example of running ReaderT with multiple items
(i, s) <- runReaderT foo ((2 :: Int) ./ "foo" ./ nil)
putStrLn $ show i <> s -- prints out "12foobar"
-- example of running StateT with multiple items
is <- execStateT bar ((2 :: Int) ./ "foo" ./ nil)
putStrLn $ show (view (item @Int) is) <> (view (item @String) is) -- prints out "12foobar"
-- Using Data.Has
-- example of running ReaderT with multiple environments
(i2, s2) <- runReaderT foo2 ((2 :: Int), "foo")
putStrLn $ show i <> s -- prints out "12foobar"
-- example of running StateT with multiple environments
(i2', s2') <- execStateT bar2 (2 :: Int, "foo")
putStrLn $ show i2' <> s2' -- prints out "12foobar"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment