我正在尝试为归纳数据类型(描述具有数据类型和模式匹配的 lambda 演算的一个版本)创建一个灵活的表示。这里的灵活性应该意味着很容易在节点上添加额外的数据(自由comonad-style)或进行替换(free monad-style)。所以这就是我所拥有的:
type Tie f φ = φ (f φ)
type Id = String
type Var = Id
type Con = Id
data Pat φ = PVar Var
| PCon Con [Tie Pat φ]
| PWildcard
data Expr φ = EVar Var
| ECon Con
| EApp (Tie Expr φ)
| ELam (Tie Pat φ) (Tie Expr φ)
当我想派生Show
实例时,麻烦就来了。当然,我可以这样做:
{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
deriving instance (Show (φ (Pat φ))) => Show (Pat φ)
deriving instance (Show (φ (Expr φ)), Show (φ (Pat φ))) => Show (Expr φ)
但是当归纳结构变得更复杂时,手动写出上下文变得笨拙。
理想情况下,我希望能够写出类似的东西
{-# LANGUAGE RankNTypes #-}
deriving instance (forall a. Show (φ a)) => Show (Expr φ)
表示函子 φ 在某种意义上应该对 Show 实例是“透明的”。
有没有办法做这样的事情?