帰納的データ型(データ型とパターンマッチングを備えたラムダ計算のバージョンを記述する)の柔軟な表現を作成しようとしています。ここでの柔軟性は、ノードにデータを追加する(無料のcomonadスタイル)または置換を行う(無料のmonadスタイル)のが簡単であることを意味するはずです。これが私が持っているものです:
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インスタンスに対して「透過的」である必要があることを表現します。
そのようなことをする方法はありますか?