我可以把它变成一个单子吗

Posted

技术标签:

【中文标题】我可以把它变成一个单子吗【英文标题】:Can I make this a Monad 【发布时间】:2018-09-17 02:09:37 【问题描述】:

我有一个类型 T(如果你有兴趣,它是我一直在探索的静态指针的包装器 here),我可以很高兴地为它编写以下操作:

unpointT :: T a -> a
apT :: T (a -> b) -> T a -> T b
bindT :: T a -> (a -> T b) -> T b

问题是,我没有不受限制的pure 函数。在我的情况下,pure 必须受到一些约束,即类型是可序列化的,例如 Binary

pureT :: C a => a -> T a

请注意,apTbindT 均不受限制。

这一切看起来都像 monad,但唯一的问题是受限制的纯。无论如何,也许有一些GADT 包装/展开,我可以让它与标准Monad 层次结构一起使用?

如果没有,是否存在替代层次结构,它限制 pure 但保持 <*>>>= 不受限制?

另请注意,T a 对于某些a 仍然有效,即使pure (x :: a) 无效,例如将T (b -> a)T bap 结合使用。

【问题讨论】:

是否存在指向您的数据类型中没有位置的指针之类的东西?我之所以这么问,是因为unpointT 的定义让我相信事实并非如此。因此,如果您可以编写extend 的声音版本,您也许可以派生出一个comonad。另一个想法是看看您是否可以使用此处概述的技术来处理限制okmij.org/ftp/Haskell/set-monad.html 我认为您需要更具体地了解您的 TC 的定义才能获得明确的答案。 @BenjaminHodgson C 通常类似于 Binary 而 T 是 hackage.haskell.org/package/static-closure-0.1.0.0/docs/… 把定义放在你的问题中 你认为你可以为你的appT构造T (a->b)吗? 【参考方案1】:

由于不满足正确的身份法则,它不会像 monad 一样工作。

bindT m pureT 的类型为 C a => T a,而 m 的类型为 T a。这两个应该始终相等,但它们甚至不是同一类型。

【讨论】:

这基本上是对的,但我觉得换一种方式会更清楚。一方面,只要m 的类型适合C a => T a,就完全有可能满足正确的恒等律;另一方面,如果m 的类型不适合——\m -> bindT m pureT 的类型为C a => T a -> T a,则无法应用该法律。 (我的观点是 T 很可能是一个 monad,但它不能是 Monad 因为约束。)

以上是关于我可以把它变成一个单子吗的主要内容,如果未能解决你的问题,请参考以下文章

Haskell 中有啥有趣的交换单子吗?

jQuery是一个单子吗

Laravel 的调试消息 - 部分是法语。我怎样才能把它变成英文?

函数单子真的提供了比函数应用函子更多的东西吗?如果是这样,是啥?

Haskell 可能永远都不会变成主流

具有验证的表单组件是否仍具有表现性?或者我应该把它变成一个容器?