我可以把它变成一个单子吗
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
请注意,apT
和 bindT
均不受限制。
这一切看起来都像 monad,但唯一的问题是受限制的纯。无论如何,也许有一些GADT
包装/展开,我可以让它与标准Monad
层次结构一起使用?
如果没有,是否存在替代层次结构,它限制 pure
但保持 <*>
和 >>=
不受限制?
另请注意,T a
对于某些a
仍然有效,即使pure (x :: a)
无效,例如将T (b -> a)
和T b
与ap
结合使用。
【问题讨论】:
是否存在指向您的数据类型中没有位置的指针之类的东西?我之所以这么问,是因为unpointT
的定义让我相信事实并非如此。因此,如果您可以编写extend
的声音版本,您也许可以派生出一个comonad。另一个想法是看看您是否可以使用此处概述的技术来处理限制okmij.org/ftp/Haskell/set-monad.html
我认为您需要更具体地了解您的 T
和 C
的定义才能获得明确的答案。
@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
因为约束。)以上是关于我可以把它变成一个单子吗的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 的调试消息 - 部分是法语。我怎样才能把它变成英文?