繁体   English   中英

管理,定相,组合monad的资源(在Scala或Haskell中)

[英]Resources on managing, phasing, composing monads (in Scala or Haskell)

我正在寻找资源讨论组成monad的良好实践。 我最紧迫的问题是我正在编写一个系统,该系统正在使用一系列状态monad而不是不同的状态类型,似乎处理这种情况的最好方法就是创建一个大的产品类型(可能是prettied)即使第1阶段对组件B不感兴趣,第2阶段仅对组件A.1感兴趣,也包括我感兴趣的所有组件。

在这类领域编写代码时,我非常感谢能够很好地讨论替代方案。 我自己的代码库是在Scala中,但我很高兴阅读有关Haskell中相同问题的讨论。

使用StateT堆栈有点困难,因为当你写入getput时,你正在谈论哪一层会让人感到困惑。 如果你在transformers风格中使用显式堆栈,那么你必须使用一堆lift ,如果你使用mtl的基于类的方法,你会完全陷入困境。

-- 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)

我们可能希望避免使用明确的产品类型的状态。 因为我们最终从我们的产品状态,各个组件的功能可以很容易地get到使用这些单个组件gets

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那就是一个名为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以隔离有状态操作,这些操作仅依赖于整个状态的子集,如incyell并确定它们在类型中的隔离。 我们还可以使用useget内部状态组件。

除此之外, 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需要一些繁重的技巧,你只能放大一些变压器层。 (今天我很不清楚你如何将这个功能添加到你自己的图层,尽管可能是这样。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM