私は論文(http://www.ittc.ku.edu/csdl/fpg/sites/default/files/Gill-09-TypeSafeReification.pdf)を読んでみることにして、シンボリックな表現型を証明することに成功しましたが、そのリストをどのように明示するかを理解できません。簡略化されたコードは次のとおりです。Data.Reifyを使用してデータのリストを検証する方法は?
{-# OPTIONS_GHC -Wall #-}
{-# Language TypeOperators #-}
{-# Language TypeFamilies #-}
{-# Language FlexibleInstances #-}
import Control.Applicative
import Data.Reify
-- symbolic expression type
data Expr a = EConst a
| EBin (Expr a) (Expr a)
deriving Show
-- corresponding node type
data GraphExpr a b = GConst a
| GBin b b
deriving Show
instance MuRef (Expr a) where
type DeRef (Expr a) = GraphExpr a
mapDeRef _ (EConst c) = pure (GConst c)
mapDeRef f (EBin u v) = GBin <$> f u <*> f v
-- this works as expected
main :: IO()
main = reifyGraph (EBin x (EBin x y)) >>= print
where
x = EConst "x"
y = EConst "y"
-- (output: "let [(1,GBin 2 3),(3,GBin 2 4),(4,GConst "y"),(2,GConst "x")] in 1")
-- but what if I want to reify a list of Exprs?
data ExprList a = ExprList [Expr a]
data GraphList a b = GraphList [GraphExpr a b]
instance MuRef (ExprList a) where
type DeRef (ExprList a) = GraphList a
-- mapDeRef f (ExprList xs) = ???????
私は一度限りのコンビネータが何を意味するのか分かりません。これは、2つの出力に共通の中間ノードがある場合、両方の出力でreifyGraphを実行し、ハッシュマップなどで明示的にCSEを実行することだけです。これはreifyGraphやStablePtrの制限ですか? – ghorn
さて、reifyGraphは単相再帰を扱うように設計されています。ここでは、式に多態的に反復する必要があります。このようなサービスを提供するデータ・レフィグマにコンビネータを作成することを実際に止めることは何もありませんが、現在は存在しません。 –