我想定义一个 monad 实例,容器 M 为 monad,包含类型 a
它应该是 Show
类的成员.类型系统应确保此约束(a
是 Show
的成员)。
我试过这样,但是M
不幸的是不是正确的种类:
data M = forall a. Show a => M a
instance Monad M where
return x = M x
所有其他实现这一目标的尝试都会遇到以下问题:自从
Monad
是构造函数类,我没有显式访问类型 a
包含的元素,所以我不能限制它。有谁知道没有定义新的解决方案
Monad
类(class)?
最佳答案
嗯,实际上可以在某种意义上限制类型构造函数的参数,使用 GADT:
data M a where
M :: (Show a) => a -> M a
不幸的是,这实际上对您没有帮助。在某种程度上,它实际上使事情变得更糟,因为没有
Monad
没有约束的实例,根本不可能编写实例。如果您查看上面的构造函数类型签名,它显然类似于
return
——这说明了为什么你正在做的事情根本上是不可能的。返回类型为:(Monad m) => a -> m a
,并且与往常一样,未绑定(bind)的类型变量在最外层被隐式地普遍量化,因此您可以将其读作“对于所有可能的类型 a
和所有可能的类型 m
是 Monad
的实例,给定值type a
你可以构造一个类型为 m a
的值。 “for all”的措辞非常直白——返回的类型不仅仅是使用类型变量,它还主动断言任何类型 a
任何事情都必须被允许。所以,简而言之,没有。没有办法做你想做的,因为标准
Monad
类明确指定相反的内容。
关于haskell - 如何在 Typeclass Show 中用 "m a"定义 Monad 实例 "a"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6763988/