如何使用Data.Reify来修改数据列表?

gho*_*orn 5 haskell

我试着阅读这篇论文(http://www.ittc.ku.edu/csdl/fpg/sites/default/files/Gill-09-TypeSafeReification.pdf)并设法重新启用我的符号表达式类型,但我可以'弄清楚如何重新列出它们的清单.这是简化的代码:

{-# 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) = ???????
Run Code Online (Sandbox Code Playgroud)

Edw*_*ETT 3

MuRef 确实无法做到这一点。GraphList 不包含 GraphList。您可以依次具体化每个 Expr 并编写一个一次性组合器将它们粉碎到您的 GraphList 中:

只需使用 traverse reifyGraph 遍历 ExprList 内容即可。

而且,后者应该都是新类型。