gpt4 book ai didi

haskell - 为什么不能为 MaybeT 派生 Show 实例?

转载 作者:行者123 更新时间:2023-12-03 14:50:43 31 4
gpt4 key购买 nike

如果我为 Identity 定义单子(monad)变压器类型,可以推导出Show实例。

newtype IdentityT f a =
IdentityT { runIdentityT :: f a }
deriving (Show)

将得出
instance Show (f a) => Show (IdentityT f a)

但是如果我为 Maybe 定义单子(monad)变压器类型
newtype MaybeT m a =
MaybeT { runMaybeT :: m (Maybe a) }
deriving (Show)

我得到错误
• No instance for (Show (m (Maybe a)))
arising from the first field of ‘MaybeT’ (type ‘m (Maybe a)’)

由于 Maybe a有一个 Show例如,我希望它能够工作并派生
instance Show (m (Maybe a)) => Show (MaybeT m a)

为什么不能呢?

最佳答案

GHC 使用启发式方法来确定实例是否保证搜索终止。
这里的终止是指,在搜索实例时,我们不会永远循环。具体来说,这是必须禁止的

instance Show a => Show a where ...

还有这个
instance Show [a] => Show a where ...

GHC 大致要求实例上下文中的约束( => 之前的部分)必须“小于”头部中的约束( => 之后)。所以,它接受这个:
instance Show a => Show [a] where ...

自从 a包含一个小于 [a] 的类型构造函数.

它也接受这个:
instance Show (f a) => Show (IdentityT f a) where ...

自从 f a包含一个小于 IdentityT f a 的类型构造函数.

然而,
instance Show (f (Maybe a)) => Show (MaybeT f a) where ...

使用相同数量的构造函数!因此,不接受确保它不会导致循环。毕竟,以后,我们可能会见面
instance Show (MaybeT f a)) => Show (f (Maybe a)) where ...

很明显,必须拒绝这两个实例中的至少一个以保证终止。 GHC 选择拒绝他们两个。
UndecidableInstances放宽了这个限制。 GHC 将接受这两种情况,现在我们有责任避免循环。

关于haskell - 为什么不能为 MaybeT 派生 Show 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44740200/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com