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

Scala和Haskell中的“复合”代数数据类型

发布时间:2020-12-16 19:11:23 所属栏目:安全 来源:网络整理
导读:在尝试用 Scala中的代数数据类型描述一部分Sql时,我遇到了创建表示数据类型的根特征的子特征的必要性.由于满足这个要求产生了一个我不确定可以用Haskell的ADT表示的代码,并且因为与Haskell不同,ADT不是Scala的本机构造,我现在想知道: 我是否正确无法表示一
在尝试用 Scala中的代数数据类型描述一部分Sql时,我遇到了创建表示数据类型的根特征的子特征的必要性.由于满足这个要求产生了一个我不确定可以用Haskell的ADT表示的代码,并且因为与Haskell不同,ADT不是Scala的本机构造,我现在想知道:

>我是否正确无法表示一个模型,例如具有“子类型”语句的类型Sql具有构造函数在Haskell中选择? (好像this可能有关).
>如果是这样,术语“ADT”是否适用于我生成的代码?
>如果是,这是否会使Scala在这方面实际上比Haskell更强大?
>如果没有,那么在Haskell中不实现此功能的原因是什么?这让我觉得我的模型中的东西可能过于复杂

这是我正在谈论的模型:

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代码.

(编辑:李大同)

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

    推荐文章
      热点阅读