未显式声明>>的自定义Monad可编译?及CMonad打印问题
自定义Monad的两个问题解答:>>操作符编译问题与Show实例报错
一、为什么不用显式声明>>操作符也能正常编译?
Haskell的Monad类中,>>是默认方法,它的实现基于你必须定义的>>=和return:
(>>) :: Monad m => m a -> m b -> m b m >> k = m >>= \_ -> k
只要你在自定义Monad的Monad实例中正确实现了>>=和return,GHC就会自动启用这个默认的>>实现,完全不需要你显式声明。
《Learn You a Haskell》里展示Maybe Monad时写出>>的实现,更多是为了直观演示这个操作符的行为(忽略前一个Monad的值,执行后一个),并非强制要求。所有Monad实例都能自动继承这个默认实现,只有当你需要自定义>>的特殊逻辑时,才需要显式重写。
二、解决"No instance for (Show (CMonad Value))"报错
这个错误的核心是:你的CMonad类型本身没有Show实例——哪怕Value已经derive了Show也没用,GHC需要知道如何将CMonad这个容器类型转换成字符串。
解决方法很直接:
自动生成Show实例(推荐):在定义
CMonad时,通过deriving (Show)让GHC自动生成实例:-- 示例:如果CMonad是newtype包装 newtype CMonad a = CMonad a deriving (Show) -- 如果是data类型同理 data CMonad a = CMonad a deriving (Show)这样只要类型参数
a(比如这里的Value)有Show实例,CMonad a就自动拥有Show实例。手动编写Show实例:如果需要自定义输出格式,可以手动实现:
instance Show a => Show (CMonad a) where show (CMonad x) = "CMonad " ++ show x
完成上述修改后,就能在GHCi中正常打印apply函数的结果了。
内容的提问来源于stack exchange,提问作者Piskator
相关产品推荐
相关产品推荐

