Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何定义此非平凡表达式类型的MuRef实例?_Haskell_Data Reify - Fatal编程技术网

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
,则代码可以工作。