0

代数类型的传统方法推荐类似的方法:

sealed trait CompositeType
final case class LeftBranch(left : String) extends CompositeType
final case class RightBranch(right : Int) extends CompoisteType
object Trivial extends CompositeType

问题是我无法CompositeType进一步扩展以获得更多选择(就像Double扩展Float提供更高的准确性并提供从 Double 向后转换为 Float 的系统)。

Scala 允许您自由定义自己的 apply 和 unapply 方法来构建和匹配代数类型的实例。

是否有任何项目试图为此类类型构建框架?

这可能对演员隐喻有用。目前,actor 接收与已知类型匹配的无类型消息(Any意味着没有类型限制)并为其他人提供安全默认值。它打破了 scala 的所有类型严格设计,并且使用更合适的类型限制演员会非常好。


更新:

阐明我的意图的示例:

sealed trait CompositeType1
final case class OtherBranch(x : Int, y : Int) extends CompositeType1
object Simple extends CompositeType1

trait ComplexChoice extends CompositionType with CompositionType1

我想创建CompositionType的不是类型层次结构中的根,而是一个实体类。这可能会进一步扩展,与其他类混合。

让我们看看一些正常的 OOP用法:

trait ContractOne
trait ContractTwo

def method(arg : ContractOne with ContractTwo)

在此示例中,函数method需要一个适合两种合约的参数。代数类型的合同是什么意思?一组可用的构造函数和匹配器。扩展代数类型的自然观点是什么?使用一些新值扩展构造函数集(就像 Double 使用更精确的浮点数扩展 Float 一样)

CompositeType显然错过了这个概念。如果我混合这两种代数类型,我会得到集合交集而不是联合。这是将代数类型表示为分层子类型集的选择方式的直接影响。它提供了更多的自由来跨越初始类型之外的选择,但它缺乏 OOP 特性,因为继承用于元素构造并且可能不用于扩展代数类型本身。

Haskell 只有一种方法可以为代数类型添加新选择:

data CompositeType = LeftBranch String | RightBranch Int | Trivial
data CompositeType1 = OtherBranch Int Int | Simple
data ComplexChoice = CompositeType | CompositeType1

ComplexChoice在 haskell 的数据类型概念中无缝定义。但是处理它变得复杂,因为我需要重新路由所有方法作为组合。这就是为什么组合是 scala 中的一种解决方案,但很麻烦且是样板的解决方案(如果没有可以为组合模式生成代码的编译器插件)

我真正需要的是这样的:

ComplexChois condense CompositeType and CompositeType1

但是对象层次结构可能只在一个方向上产生。

因此需要以其他方式定义代数类型。它有空间,因为原始特征的无限扩展并不是真正需要的,并且大多数此类特征都与sealed关键字一起使用。因此,可以使用其他一些比扩展功能更弱的机制来表示数据类型。

4

1 回答 1

1

正如您所注意到的,objects 是派生子类型的行尾。在这种情况下,您可以创建另一个级别的中间抽象类型,从中派生以下子类型(单例或其他)Trivial

sealed trait Trivial extends CompositeType
object Trivia extends Trivial { ... }
class Triviality extends Trivia(...) { ... } \
...
于 2013-03-04T15:48:01.823 回答