Я работаю над инструментом анализа / преобразования языка, который позволяет распространять изменения в AST через серию проходов преобразования.Чтобы сделать API более привлекательным, я бы хотел связать серию вызовов reifyGraph во времени.
Для начала, шаблон:
import Data.Reify
import Data.Reify.Graph
import Data.Functor.Foldable
import Data.Functor.Foldable.TH
import Control.Monad.IO.Class
Некоторая простота использования кода, который позволяет мне получить экземпляр MuRef с классами, которые мы находим в схемах рекурсии:
newtype MuReify a = MuR { getRec :: a }
type instance Base (MuReify a) = Base a
instance (Recursive t, Traversable (Base t)) => MuRef (MuReify t) where
type DeRef (MuReify t) = Base t
mapDeRef f = traverse (f . MuR) . project . getRec
reifyMuRef :: (Recursive s, Traversable (Base s)) => s -> IO (Graph (Base s))
reifyMuRef = reifyGraph . MuR
Используемый мной игрушечный язык, взятый непосредственно из документации по схемам рекурсии:
data Expr a
= Lit a
| Add (Expr a) (Expr a)
| Expr a :* [Expr a]
deriving (Show)
makeBaseFunctor ''Expr
deriving instance (Show a, Show f) => Show (ExprF a f)
Учитывая все вышеизложенное, я хочу иметь возможность связать серию вариантов, чтобы я мограсскажите, какие термины распределяются между звонками, а также в пределах определенного графика.
У меня есть небольшой фрагмент, который помогает продемонстрировать, что я хотел бы:
main :: IO ()
main = do
let l3 = Lit 3
l5 = Lit 5
add = Add l3 add
mul = l5 :* [Lit 2, add]
foo = Add add mul
bar = Add foo l3
print =<< traverse reifyMuRef [bar,mul,foo]
Когда вы запустите вышеприведенное, вы получите (без дополнительного форматирования):
bar = let [(1,AddF 2 4)
,(2,AddF 3 5)
,(3,AddF 4 3)
,(4,LitF 3)]
,(5,6 :*$ [7,3])
,(6,LitF 5)
,(7,LitF 2)]
in 1
mul = let [(1,2 :*$ [3,4])
,(2,LitF 5)
,(3,LitF 2)
,(4,AddF 5 4)
,(5,LitF 3)]
in 1
foo = let [(1,AddF 2 4),
,(2,AddF 3 2)
,(3,LitF 3)
,(4,5 :*$ [6,2])
,(5,LitF 5)
,(6,LitF 2)]
in 1
Заметьте, как, хотя существует один экземпляр, где мы определяем Lit 3
, соответствующий термин LitF 3
обнаруживается с разными индексами в каждом из графиков?
За исключением полноценного анализа графа, есть ли какой-нибудь способ для меня выяснить, какие термины эквивалентны во всех выражениях?