Scala和Haskell中的“复合”代数数据类型
在尝试用
Scala中的代数数据类型描述一部分Sql时,我遇到了创建表示数据类型的根特征的子特征的必要性.由于满足这个要求产生了一个我不确定可以用Haskell的ADT表示的代码,并且因为与Haskell不同,ADT不是Scala的本机构造,我现在想知道:
>我是否正确无法表示一个模型,例如具有“子类型”语句的类型Sql具有构造函数在Haskell中选择? (好像this可能有关). 这是我正在谈论的模型: sealed trait Sql sealed trait Statement extends Sql sealed case class Union ( left : Statement,right : Statement ) extends Statement sealed case class Select ( /** other fields don't matter **/ where : Where ) extends Statement sealed trait Where extends Sql sealed case class And ( left : Where,right : Where ) extends Where sealed case class Or ( left : Where,right : Where ) extends Where sealed case class Equals ( /** fields don't matter **/ ) extends Where 解决方法
1.不,因为您的根特征是密封的,所以可以将呈现的层次结构表示为ADT:
data Sql = Statement Statement | Where Where -- ^ This is the *type* called `Statement` -- ^ This is the *constructor* called `Statement` data Statement = Union Statement Statement | Select Where data Where = And Where Where | Or Where Where | Equals 在这种情况下,这是可能的,因为您能够枚举数据类型的所有“子类”(在本例中为Sql),这使得将它们转换为ADT构造函数成为可能.如果要允许用户任意添加“构造函数”/“子类”,则很难将类型层次结构模拟为ADT. 2.术语ADT从不适用于Scala代码,因为Scala在语言中缺少ADT.但是,您所呈现的类与ADT类似,所以我说“足够接近”. 3&这些语言有不同的优点和缺点. Haskell可以模拟每个Scala语言特性,Scala可以模拟每个Haskell特性,因为这两种语言都是完整的,并允许不同级别的元编程. Haskell当然有模板Haskell,它允许模拟任何东西 – 你可能使用TH能够在Haskell文件中编写Scala代码并将其编译为Haskell. Haskell中不需要对象和继承,并且Scala中大多不需要ADT,因此没有理由比较这两者.大多数面向对象的功能也可以使用简单的Haskell类型类和数据类型以及使用模块边界进行模拟.可以使用案例类在Scala中模拟ADT,并且可以使用隐式参数和隐式对象实例模拟Haskell类型类. 但是,我会说它通常更容易模拟Haskell中的某些Scala功能,因为Haskell允许比Scala更多的“隐式语言扩展”.我的意思是,如果你想在Scala中模拟Haskell Monads,你必须在使用Monads的部分中编写大量代码,而如果你想模拟,比如说,Scala在Haskell中的分隔连续或隐式参数,你可以简单地编写一个Monad实例(用于continuation)或一个多参数类型(用于隐式参数),并且稍后在实际函数中编写的代码看起来非常接近Scala代码而没有太多锅炉盘子.许多(如果不是大多数)Scala的高级功能也来自Haskell或OCaml,因此它们已经存在并且不需要翻译. 换句话说:添加新功能所需的复杂代码只需要添加到Haskell中的一个位置,之后它可以非常容易地在多个位置使用,而你经常需要在你的任何地方添加大量“噪音”如果要模拟Haskell功能,请使用Scala代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |