Haskell 如何定义此非平凡表达式类型的MuRef实例?
考虑一种玩具嵌入式语言:Haskell 如何定义此非平凡表达式类型的MuRef实例?,haskell,data-reify,Haskell,Data Reify,考虑一种玩具嵌入式语言: data Expr = App Expr Expr | Lam Pat Expr | Case Expr [(Pat, Expr)] 我想通过使用观察Expr表达式中的任何隐式共享。为此,我需要一个对应于图节点的代理类型: data ExprF e = AppF e e | LamF Pat e | Case e [(Pat, e)] 以及MuRef类的一个实例。我可以为App和Lam构造函数轻松提供mapDeRef的定义,但我不确
data Expr =
App Expr Expr
| Lam Pat Expr
| Case Expr [(Pat, Expr)]
我想通过使用观察Expr
表达式中的任何隐式共享。为此,我需要一个对应于图节点的代理类型:
data ExprF e =
AppF e e
| LamF Pat e
| Case e [(Pat, e)]
以及MuRef
类的一个实例。我可以为App
和Lam
构造函数轻松提供mapDeRef
的定义,但我不确定如何处理与Case
对应的定义:
instance MuRef Expr where
type DeRef Expr = ExprF
mapDeRef f (App e0 e1) = AppF <$> f e0 <*> f e1
mapDeRef f (Lam p e) = LamF p <$> f e
mapDeRef f (Case e pes) = Case <$> f e <*> ?
instance MuRef Expr where
...
mapDeRef f (Case e pes) = Case <$> f e <*> f pes
Could not deduce (u ~ [(Pat, u)])
from the context (Applicative f)
bound by the type signature for
mapDeRef :: Applicative f =>
(forall b. (MuRef b, DeRef Expr ~ DeRef b) => b -> f u)
-> Expr -> f (DeRef Expr u)
但是对于案例
的原始mapDeRef
绑定,没有运气:
instance MuRef Expr where
type DeRef Expr = ExprF
mapDeRef f (App e0 e1) = AppF <$> f e0 <*> f e1
mapDeRef f (Lam p e) = LamF p <$> f e
mapDeRef f (Case e pes) = Case <$> f e <*> ?
instance MuRef Expr where
...
mapDeRef f (Case e pes) = Case <$> f e <*> f pes
Could not deduce (u ~ [(Pat, u)])
from the context (Applicative f)
bound by the type signature for
mapDeRef :: Applicative f =>
(forall b. (MuRef b, DeRef Expr ~ DeRef b) => b -> f u)
-> Expr -> f (DeRef Expr u)
实例MuRef Expr其中
...
mapDeRef f(案例e pes)=案例f e f pes
无法推断(u~[(Pat,u)])
从上下文(应用程序f)
由的类型签名绑定
mapDeRef::Applicative f=>
(对于所有b.(MuRef b,DeRef Expr~DeRef b)=>b->f u)
->Expr->f(DeRef Expr u)
是否可以为
案例
模式正确定义mapDeRef
?是否有我忽略的简单内容?可以为原始类型定义实例:
{-# LANGUAGE TypeFamilies, TupleSections #-}
import qualified Data.Traversable as T
import Data.Reify
import Control.Applicative
data Expr =
App Expr Expr
| Lam Pat Expr
| Case Expr [(Pat, Expr)]
data ExprF e =
AppF e e
| LamF Pat e
| CaseF e [(Pat, e)]
data Pat -- placeholder
instance MuRef Expr where
type DeRef Expr = ExprF
mapDeRef f (App e0 e1) = AppF <$> f e0 <*> f e1
mapDeRef f (Lam p e) = LamF p <$> f e
mapDeRef f (Case e pes) = CaseF <$> f e <*> T.traverse (\(pat, exp) -> (pat,) <$> f exp) pes
@你是说为了使用这个实例?(对我来说,这是一种检查)哦,我很傻,你在列表上使用它,所以你不需要这样的例子。太棒了,谢谢。我第一次试着和特拉弗斯混日子,但什么都没用。干杯。@jtobin您应该使用GHC 7.8的TypedHoles功能,在这种情况下,这是一个巨大的帮助。
\u 2
与2元组的遍历
相同。所以(traverse.traverse)f pes
也可以工作。如果将CaseF
更改为casefe
,则代码可以工作。