В разделе 2.3 эти действительно замечательные заметки о безусловных окончательных интерпретаторах для DSL, Олег Киселев показывает, как решить проблему разбора сериализованной DSL выражение один раз и интерпретирует его несколько раз.
Вкратце, он показывает, что "поддельный полиморфизм первого класса" с типами
newtype Wrapped = Wrapped (∀ repr. ExpSYM repr ⇒ repr)
fromTree :: String → Either ErrMsg Wrapped
не является удовлетворительным, потому что он не расширяем: для каждого набора ограничений на repr
мы должны иметь разные Wrapper
/fromTree
. Таким образом, я склонен использовать его решение интерпретатора дубликатора. Этот вопрос касается использования этого интерпретатора с помощью HOAS.
В частности, рассмотрите следующий язык для привязок к целевому языку:
class Lam repr where
lam :: (repr a -> repr b) -> repr (a -> b)
app :: repr (a -> b) -> repr a -> repr b
У меня возникли проблемы с предоставлением звукового экземпляра класса Lam
для моего интерпретатора duplicator. Вот что у меня есть:
data Dup repr1 repr2 a = Dup {unDupA :: repr1 a, unDupB :: repr2 a}
instance (Lam repr1, Lam repr2) => Lam (Dup repr1 repr2) where
lam f = Dup (lam $ unDupA . f . flip Dup undefined) (lam $ unDupB . f . Dup undefined)
app (Dup fa fb) (Dup a b) = Dup (app fa a) (app fb b)
Есть ли способ дать рекурсивный экземпляр Lambda
для чего-то вроде моего типа Dup
, который не включает undefined
?
Я также попытался использовать более мощную версию Lam
из этой статьи, которая позволяет монадическим переводчикам с помощью HOAS, хотя я и сделал Посмотрите, как это поможет мне с моим экземпляром для Dup
. Решение с использованием любой версии Lam
с HOAS было бы здорово!
*: Олег показал, как определить звуковой экземпляр, используя индексы Bruijn, но меня действительно интересует решение для HOAS.Суб >
class Lam repr where
lam :: repr (a,g) b -> repr g (a -> b)
app :: repr g (a->b) -> repr g a -> repr g b
data Dup repr1 repr2 g a = Dup{d1:: repr1 g a, d2:: repr2 g a}
instance (Lam repr1, Lam repr2) => Lam (Dup repr1 repr2) where
lam (Dup e1 e2) = Dup (lam e1) (lam e2)
app (Dup f1 f2) (Dup x1 x2) = Dup (app f1 x1) (app f2 x2)