Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
如何在Scala中表达Haskell的这种存在类型?_Scala_Haskell_Typeclass_Existential Type - Fatal编程技术网

如何在Scala中表达Haskell的这种存在类型?

如何在Scala中表达Haskell的这种存在类型?,scala,haskell,typeclass,existential-type,Scala,Haskell,Typeclass,Existential Type,我正在尝试将基于类型类的解决方案应用于Scala。我现在的代码如下。我在Scala中表达存在类型Exp时遇到问题 我怎样才能实现同样的目标 对象表达问题{ //a级评估在哪里 //eval::a->Int 特征评估[A]{ def eval(出口:A):整数 } //数据Exp=forall t.Eval t=>Expr t 密封抽象类 案例类Expr[T](值e:T)(隐式ev:Eval[T])扩展了Exp //实例Eval Exp where //eval(Expr e)=eval e 隐式

我正在尝试将基于类型类的解决方案应用于Scala。我现在的代码如下。我在Scala中表达存在类型
Exp
时遇到问题

我怎样才能实现同样的目标

对象表达问题{
//a级评估在哪里
//eval::a->Int
特征评估[A]{
def eval(出口:A):整数
}
//数据Exp=forall t.Eval t=>Expr t
密封抽象类
案例类Expr[T](值e:T)(隐式ev:Eval[T])扩展了Exp
//实例Eval Exp where
//eval(Expr e)=eval e
隐式val exprInstance=新值[Exp]{
def eval(expr:Exp)=expr match{case expr(e,ev)=>ev.eval(e)}
}
//                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//问题就在这里
//数据BaseExp=Const Int | Add Exp Exp | Mul Exp Exp
密封抽象类BaseExpr
case类Const(c:Int)扩展了BaseExpr
case类Add(lhs:Exp,rhs:Exp)扩展了BaseExpr
case类Mul(lhs:Exp,rhs:Exp)扩展了BaseExpr
//实例Eval BaseExp,其中
//评估(常数n)=n
//评估(加上评估)=评估a+评估b
//评估(多个a b)=评估a*b
隐式val BASEXPRINSTANCE=new Eval[BaseExpr]{
def eval(baseExpr:baseExpr)(隐式e:eval[Exp]):Int=
baseExpr匹配{
案例常数(c)=>c
案例添加(左侧、右侧)=>e.eval(左侧)+e.eval(右侧)
案例Mul(左侧、右侧)=>e.eval(左侧)+e.eval(右侧)
}
}
//TODO:有没有一种更简单的方法可以使所有这些都隐式地可转换?
//
//以下内容似乎不起作用:
//
//隐式def baseExprToExp[T Int
特征评估[A]{
def eval(出口:A):整数
}
//////////////////////////////////////////
//这就是魔法
//
//数据Expr=forall t.Eval t=>Expr t
性状表达{
T型
val t:t
Eval evalInst:Eval[T]
}
对象表达式{
def应用[T0:Eval](T0:T0)=新表达式{
类型T=T0
val t=t0
val evalInst=隐式[Eval[T]]
}
}
//需要默认装箱
隐式定义框[T:Eval](T:T)=表达式(T)
//实例Eval Expr where
//eval(Expr e)=eval e
隐式对象表达式扩展了Eval[Expr]{
def eval(expr:expr)=expr.evalInst.eval(expr.t)
}
//data BASEXPR=Const Int | Add Expr Expr | Mul Expr Exp
密封抽象类BaseExpr
case类Const(c:Int)扩展了BaseExpr
案例类添加(lhs:Expr,rhs:Expr)扩展了BaseExpr
case类Mul(lhs:Expr,rhs:Expr)扩展了BaseExpr
//实例Eval BaseExpr,其中
//评估(常数n)=n
//评估(加上评估)=评估a+评估b
//评估(多个a b)=评估a*b
隐式对象baseExprInstance扩展了Eval[BaseExpr]{
def eval(baseExpr:baseExpr):整数=
baseExpr匹配{
案例常数(c)=>c
案例添加(左、右)=>exprInstance.eval(左)+exprInstance.eval(右)
案例Mul(左、右)=>exprInstance.eval(左)+exprInstance.eval(右)
}
}
//所有基表达式的隐式转换

隐式def baseExprToExpr[T您的问题是您正在使用一个提取器(
unapply
),但忽略了隐式默认情况下不会作为
unapply
的一部分公开这一事实

所以这一行:

def eval(expr: Exp) = expr match { case Expr(e, ev) => ev.eval(e) }
没有
case-Expr(e,ev)
,只有
case-Expr(e)
,因为只有
e
是公开的。要么编写自定义提取器,要么找到不同的方法

Scala确实提供了形式的存在类型:

Expr[T] forSome { type T})
它有一个可用的速记类型符号:
Expr[\uz]

不过,您的代码还有一些问题:

如果您在
eval
上定义
implicit
,则所有实现者都必须使用该特定签名实现
eval
函数,您不能像在中那样使用签名中不包含隐式的实现来覆盖
eval

 implicit val baseExprInstance = new Eval[BaseExpr] {
    def eval(baseExpr: BaseExpr)(implicit e: Eval[Exp]): Int =
      baseExpr match {
        case Const(c)      => c
        case Add(lhs, rhs) => e.eval(lhs) + e.eval(rhs)
        case Mul(lhs, rhs) => e.eval(lhs) + e.eval(rhs)
      }
  }
接下来,您需要在
Expr
上进行
T
逆变,或者进行
SubExpr
扩展
Exp
,您在这里遇到了一个问题:

  // instance Eval SubExp where
  //   eval (Sub a b) = eval a - eval b
  implicit val subExprInstance = new Eval[SubExpr] {
    def eval(subExpr: SubExpr)(implicit e: Eval[SubExpr]): Int =
      e.eval(subExpr.lhs) - e.eval(subExpr.rhs)
  }

如果要尝试匹配类型签名,
implicit e:Eval[SubExpr]
可以计算
T>:SubExpr
的类型,但您需要的是
Eval
Exp
隐式值较低(
unapply
),但忽略了这样一个事实,即默认情况下隐式不会作为
的一部分公开

所以这一行:

def eval(expr: Exp) = expr match { case Expr(e, ev) => ev.eval(e) }
没有
case-Expr(e,ev)
,只有
case-Expr(e)
,因为只有
e
是公开的。要么编写自定义提取器,要么找到不同的方法

Scala确实提供了形式的存在类型:

Expr[T] forSome { type T})
它有一个可用的速记类型符号:
Expr[\uz]

不过,您的代码还有一些问题:

如果您在
eval
上定义
implicit
,则所有实现者都必须使用该特定签名实现
eval
函数,您不能像在中那样使用签名中不包含隐式的实现来覆盖
eval

 implicit val baseExprInstance = new Eval[BaseExpr] {
    def eval(baseExpr: BaseExpr)(implicit e: Eval[Exp]): Int =
      baseExpr match {
        case Const(c)      => c
        case Add(lhs, rhs) => e.eval(lhs) + e.eval(rhs)
        case Mul(lhs, rhs) => e.eval(lhs) + e.eval(rhs)
      }
  }
接下来,您需要在
Expr
上进行
T
逆变,或者进行
SubExpr
扩展
Exp
,您在这里遇到了一个问题:

  // instance Eval SubExp where
  //   eval (Sub a b) = eval a - eval b
  implicit val subExprInstance = new Eval[SubExpr] {
    def eval(subExpr: SubExpr)(implicit e: Eval[SubExpr]): Int =
      e.eval(subExpr.lhs) - e.eval(subExpr.rhs)
  }

如果要尝试匹配类型签名,
implicit e:Eval[SubExpr]
可以计算
T>:SubExpr
的类型,但您需要的是
Exp
implicit for
eval

更低的
Exp
,谢谢!我更新了我的最新帖子,请看一看。在新方法中,我唯一不喜欢的是,我必须删除您指出的隐式参数,但我必须明确指定每一次都要解释。我有什么办法可以避免吗?谢谢!@CălinCruceru我恐怕没有更多的时间了,