如何将GHC.Ptr实现为Monad实例?现有代码报错求解析
问题:将GHC.Ptr实现为Monad实例时出现类型不匹配错误
我尝试把GHC.Ptr实现为Monad实例,代码如下:
instance Monad Ptr where return = pure (>>=) (Ptr t) f = f t
运行后抛出错误:
• Couldn't match a lifted type with an unlifted type When matching types a :: * GHC.Prim.Addr# :: TYPE 'GHC.Types.AddrRep • In the first argument of ‘f’, namely ‘t’ In the expression: f t In an equation for ‘>>=’: (>>=) (Ptr t) f = f t • Relevant bindings include f :: a -> Ptr b (bound at RegionalMemory.hs:16:19) (>>=) :: Ptr a -> (a -> Ptr b) -> Ptr b (bound at RegionalMemory.hs:16:5) | 16 | (>>=) (Ptr t) f = f t | ^
请问我哪里出错了?
错误原因与解释
Ptr的真实结构
先明确Ptr的定义:newtype Ptr a = Ptr Addr#。这里的类型参数a是幽灵类型(phantom type)——它只用来标记指针指向的内容类型,并不会出现在构造函数的实际参数里。你模式匹配出来的t是底层的Addr#,这是GHC提供的unlifted原始类型,不属于普通Haskell值的*类型范畴。类型不匹配的根源
你写的>>=函数中,f的类型是a -> Ptr b,要求传入一个a类型的普通值,但你传给它的t是Addr#类型的原始指针。这两种类型完全不兼容:
a是普通的lifted类型(属于*kind)Addr#是unlifted的底层类型(属于TYPE 'AddrRep)
这就是错误提示里“无法匹配lifted类型和unlifted类型”的原因。
- 语义上的矛盾
Monad的核心语义是“容器”:Ptr a应该代表“包含一个a值的容器”,但Ptr的实际设计只是底层原始指针的类型安全包装,它根本不持有a类型的值。所以>>=需要提取容器内的a值传给f的逻辑,在Ptr这里从根本上就不成立。
总结:你误解了Ptr的设计意图,它不是用来包裹普通Haskell值的容器类型,因此不适合作为Monad实例。
内容的提问来源于stack exchange,提问作者kesarling
相关产品推荐
相关产品推荐

