单子变换器是否需要访问单子的内部结构?

10

编写单子变换器是否需要访问单子的内部结构?

例如:我想为来自Data.Binary.Get的Get单子创建GetT变换器,但是该模块不公开Get单子的内部结构。这是否意味着我唯一的选择是直接将GetT添加到Data.Binary.Get模块中?


2
我认为通常情况下是相反的。单子变换器定义了单子的实际实现,然后将其应用于“Identity”单子以获得该单子的“基本”实例(例如,将“StateT”应用于“Identity”以获取“State”)。注意,我不确定这一点 :) - Riccardo T.
1个回答

11

通常情况下,是的。看这个例子,内部单子(在这里是列表单子)如何“取消”外部单子“先前”的操作:

> execWriterT (tell "Hi" >> tell "Ho" >> lift [()])
["HiHo"]
> execWriterT (tell "Hi" >> tell "Ho" >> lift [])
[]

假设您可以将每个单子转换为单子变换器。那么您将能够构建一个IOT单子变换器,此代码将发射导弹,但然后撤销它:

> execIOT (launchMissile >> lift [])
因此,如果不查看定义,就无法将任意单子转换为单子变换器。

我是否正确理解,您将此案例作为一个不需要获取内部结构信息的例子?但是实际上您使用了内部 monad 是 list 的事实。 - Victor Denisov
我有一些代码,使用Handler通过套接字进行通信。 - Victor Denisov
1
如果问题是“编写单子变换器是否需要访问内部结构”,那么答案不是“是”吗? - John L
1
@VictorDenisov - 鉴于这些要求,您可能需要研究各种迭代器类型之一(iteratee、conduit、pipes等等选项)。该问题几乎直接处于它们的设计空间中。 - John L
为什么 execIOT (launchMissile >> lift []) 需要先发射一枚导弹,然后再“撤销”它呢?我本来以为表达式 launchMissile >> lift [] 只是一个 IOT [] 值,不会 发射任何导弹,所以当执行它时,execIOT 不需要做任何事情。 - winitzki
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接