4

帰納的データ型(データ型とパターンマッチングを備えたラムダ計算のバージョンを記述する)の柔軟な表現を作成しようとしています。ここでの柔軟性は、ノードにデータを追加する(無料の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インスタンスに対して「透過的」である必要があることを表現します。

そのようなことをする方法はありますか?

4

1 に答える 1

1

考えられる解決策には、

class Show1 f where
  showsPrec1 :: Show a => Int -> f a -> ShowS

この型クラスは で同様に定義されていprelude-extrasます。残念ながら、Haskell の導出メカニズムはそれを利用しないため、使用できませんでした。可能な代替手段は、「派生」ではありませんが、少なくとも自明なインスタンスを作成するために新しいGHC.Genericsandを使用することです。DefaultSignatures

instance (Show1 φ) => Show (Pat φ)
instance (Show1 φ) => Show (Expr φ)

難しい部分は次のとおりです。実際にGHC.Generics. 使えそうなものは

instance (Show1 f, Show a) => Show (f a) where showsPrec = showsPrec1

ただし、これにはOverlappingInstances(他の問題に加えて) 要求するという極端な欠点があります。考えられる解決策の 1 つは、 shadows であるクラスを定義することですShow

class Show' a where showsPrec' ...
instance (Show1 f, Show' a) => Show' (f a) where ...

すべてのGHC.Generics機構 ( GShowGShow1、デフォルトの署名など​​) が整っていれば、最終結果はそれほどひどいものにはなりません。

instance (Show1 φ) => Show' (Pat φ)
instance (Show1 φ) => Show (Pat φ) where showsPrec = showsPrec'
instance (Show1 φ) => Show' (Expr φ)
instance (Show1 φ) => Show (Expr φ) where showsPrec = showsPrec'

ただし、必要な作業量がそれほど悪くない (かなり悪い) ふりをすると、一部の型は手動で転送するように設定する必要がありshowsPrec'( showsPrecCharなどBool)、使用されるすべての型をインスタンスにする必要があります。のインスタンスである場合Show'は些細なことですが、これは確かに便利ではありません。GenericGeneric1

于 2013-04-09T20:57:52.593 に答える