Resources for managing, phasing, composing monads (in Scala or Haskell)

I am looking for resources to discuss good practices for writing monads. My most pressing problem is that I am writing a system that uses a number of state monads for various types of states, and it seems that the best way to deal with this situation is to simply create one large type of product (possibly as a record / class), covering all the components that interest me, although stage 1 is not interested in component B, and phase 2 is only interested in component A.1.

I would appreciate a good discussion of alternatives when writing code in this area. My own code base is in Scala, but I am happy to read discussions about the same issues in Haskell.

+4
source share
1 answer

It is a little difficult to use stacks StateTbecause it becomes confusing as to which layer you are talking to when you write getor put. If you use an explicit style stack transformers, you need to use a bunch lift, and if you use a class mtl-based class method , you are completely stuck.

-- using transformers explicit stack style
type Z a = StateT Int (StateT String IO) a

go :: Z ()
go = do int <- get
        str <- lift get
        replicateM int (liftIO $ putStrLn str)

We could avoid this mess with an explicit type of product condition. Since we derive functions from our product state for each individual component, it is easy to getinsert into those individual components usinggets

data ZState = ZState { int :: Int, str :: String }
type Z a = StateT ZState IO a

go :: Z ()
go = do i <- gets int
        s <- gets str
        replicateM i (liftIO $ putStrLn s)

: (1) put, (2) int , str. .

lens -savvy, zoom

-- the real type is MUCH more general
zoom :: Lens' mother child -> StateT child m a -> StateT mother m a 

"" . , , :

data ZState = ZState { _int :: Int, _str :: String }
makeLenses ''ZState

type Z = StateT ZState IO a

inc :: MonadState Int m => m ()
inc = modify (+1)

yell :: MonadState String m => m ()
yell = modify (map toUpper)

go :: Z ()
go = do zoom int $ do inc
                      inc
                      inc
        zoom str yell
        i <- use int
        s <- use str
        replicateM i (liftIO $ putStrLn s)

- zoom in , inc yell . get use.

, zoom zoom , .

type Z a = EitherT String (ListT (StateT ZState IO)) a

>>> :t zoom int :: EitherT String (ListT (StateT Int IO)) a -> Z a
zoom int :: EitherT String (ListT (StateT Int IO)) a -> Z a

, zoom , . ( , , , , .)

+8

Source: https://habr.com/ru/post/1530111/


All Articles