3

したがって、「注釈」タイプによってパラメーター化された、多数のケースを持つ AST データ型があります。

data Expr a = Plus a Int Int
    | ...
    | Times a Int Int

私は注釈型ST、そしていくつかの機能を持っていますf :: S -> T。Expr 値内で発生するそれぞれの変換を使用してExpr S、 を取得して に変換したいと考えています。Expr TfS

SYB またはジェネリックを使用してこれを行い、すべてのケースでパターン マッチを回避する方法はありますか? こういうのに向いているタイプのようです。私はSYBに精通していないため、具体的な方法を知ることができません。

4

2 に答える 2

2

あなたのフォローアップの質問に基づいて、ジェネリック ライブラリは Functor よりもあなたの状況に適しているようです。SYB のwiki ページにある関数を使用することをお勧めします。

{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables, FlexibleContexts #-}
import Data.Generics
import Unsafe.Coerce

newtype C a = C a deriving (Data,Typeable)

fmapData :: forall t a b. (Typeable a, Data (t (C a)), Data (t a)) =>
    (a -> b) -> t a -> t b
fmapData f input = uc . everywhere (mkT $ \(x::C a) -> uc (f (uc x)))
                    $ (uc input :: t (C a))
    where uc = unsafeCoerce

余分なタイプの理由はC、同じタイプのフィールドが発生するという問題のあるコーナー ケースを回避するためですa(詳細は wiki を参照)。の呼び出し元はfmapDataそれを見る必要はありません。

この関数には、実際の と比較していくつかの追加要件があります。 forおよびforfmapのインスタンスが必要です。あなたの場合はです。つまり、 の定義にa を追加するだけでなく、使用しているもののスコープ内にインスタンスを含める必要があります。TypeableaDatat at aExpr aderiving DataExprDataa

于 2014-12-28T09:09:47.083 に答える