加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中键入类

发布时间:2020-12-16 09:10:51 所属栏目:安全 来源:网络整理
导读:在 Haskell有一个背景我正在试图熟悉 Scala. 我遇到一些问题,试图将一个小的,可扩展的表达式语言从Haskell转换成Scala.编写可与两种新数据变体和操作进行扩展的数据类型的基本问题通常称为expression problem. 我在Haskell中的原始解决方案使用具有约束的类
在 Haskell有一个背景我正在试图熟悉 Scala.

我遇到一些问题,试图将一个小的,可扩展的表达式语言从Haskell转换成Scala.编写可与两种新数据变体和操作进行扩展的数据类型的基本问题通常称为expression problem.

我在Haskell中的原始解决方案使用具有约束的类型类和实例声明.我的表达的基础定义如下:

module Expr where

class Expr e where
 eval :: e -> Integer

data Lit = Lit Integer
instance Expr Lit where
  eval (Lit l) = l

data Plus a b = (Expr a,Expr b) => Plus a b
instance (Expr a,Expr b) => Expr (Plus a b) where
  eval (Plus x y) = (eval x) + (eval y)

然后,我有一个数据扩展名加上乘法:

module ExprWithMul where
import Expr

data Mul a b = (Expr a,Expr b) =>  Mul a b
instance (Expr a,Expr b) => Expr (Mul a b) where
  eval (Mul x y) = (eval x) * (eval y)

让我们把漂亮的打印机作为一个运行的扩展:

module FormatExpr where
import Expr

class (Expr t) => FormatExpr t where
  format :: t -> String

instance FormatExpr Lit where
  format (Lit l) = show l

instance (FormatExpr a,FormatExpr b) => FormatExpr (Plus a b) where
  format (Plus x y) = "(" ++ (format x) ++ "+" ++ (format y) ++ ")"

最后,在第四个模块中,可以组合两个独立的扩展:

module FormatExprWithMult where
import FormatExpr
import ExprWithMul

instance (FormatExpr a,FormatExpr b) => FormatExpr (Mul a b) where
  format (Mul x y) = "(" ++ (format x) ++ "*" ++ (format y) ++ ")"

现在我的问题:通常类型的类从haskell被转换为概念模式与Scala的潜意识.这是我有多远:

abstract class Expr[A] { // this corresponds to a type class
  def eval(e:A): Int;
}

case class Lit(v: Int)
implicit object ExprLit extends Expr[Lit] {
 def eval(e: Lit) = x.v;
}
case class Plus[A,B] (e1: A,e2: B) (implicit c1: Expr[A],c2: Expr[B])

在这里我坚持执行Plus的隐式对象.如何使用类型参数和约束声明隐式对象?

我知道Scala中的表达式问题还有其他解决方案,但我对此版本尤其感兴趣.

感谢大家阅读我有点冗长的问题.

解决方法

第一次尝试(有缺陷):

case class Plus[A,c2: Expr[B]) {
    implicit object ExprPlus extends Expr[Plus[A,B]] { 
        def eval(p:Plus[A,B]) = c1.eval(p.e1) + c2.eval(p.e2)
    }
}

编辑1:

上面的功能不够强大(你不能添加两个Plus表达式),并且隐藏的证人不需要在Plus case类里面定义…尝试改为:

case class Plus[A,e2: B) (implicit val c1: Expr[A],c2: Expr[B])
implicit def ExprPlus[A,B](implicit c1: Expr[A],c2: Expr[B]) = 
    new Expr[Plus[A,B]) = c1.eval(p.e1) + c2.eval(p.e2)
    }

编辑2:

这是一个(也许)稍微更习惯的版本:

case class Plus[A: Expr,B: Expr] (e1: A,e2: B)
implicit def ExprPlus[A: Expr,B: Expr] = new Expr[Plus[A,B]] {
    def eval(p:Plus[A,B]) = implicitly[Expr[A]].eval(p.e1) + 
                             implicitly[Expr[B]].eval(p.e2)
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读