类型构造函数作为返回类型

问题描述 投票:7回答:2

在Scala中,我可以定义Algebraic Data Type

scala> sealed trait Maybe[A]
defined trait Maybe

scala> case class Just[A](x: A) extends Maybe[A]
defined class Just

scala> case object NothingHere extends Maybe[Nothing]
defined object NothingHere

可以返回类型为f的函数Maybe[A]。>>

scala> def f[A](x: A): Maybe[A] = Just(x)
f: [A](x: A)Maybe[A]

但是,也可以指定返回Just[A]

scala> def f[A](x: A): Just[A] = Just(x)
f: [A](x: A)Just[A]

现在我将在Haskell中进行类似的练习:

Prelude> data Option a = None | Some a deriving Show
Prelude> let f x = Some x :: Option Int
Prelude> f 10
Some 10

但是,我无法设置类型构造函数

的返回类型。
Prelude> let f x = Some x :: Some Int

<interactive>:10:21:
    Not in scope: type constructor or class `Some'
    A data constructor of that name is in scope; did you mean DataKinds?
Prelude> let f x = None :: None

Scala的Just是一个类,即合法的返回类型,这是简单的区别吗?而在Haskell中,类型构造器

不能是返回类型吗?

在Scala中,我可以定义一个代数数据类型:scala>密封的特征Maybe [A]定义的特征Maybe scala> case类Just [A](x:A)扩展了Maybe [A]定义的类Just scala> case对象。 ..

scala haskell return-type algebraic-data-types type-constructor
2个回答
11
投票

不同之处在于Scala选择实施ADT的方式。 Scala使用案例类以OOP样式扩展特征,因此每种案例都是其自己的类型,而Haskell只是具有针对同一类型的多个构造函数。由于它们不是单独的类型,而是本质上只是单独的函数,因此您无法在类型级别上对其进行区分。有一些扩展使您能够区分类型级别,但它与Scala的功能不同。并且试图将Haskell的类型系统适合于Scala的类型系统可能不是最好的主意。


0
投票

bhelkir和leftaroundabout指出了为什么您不能在Haskell中完全做到这一点:没有子类型的概念。

© www.soinside.com 2019 - 2024. All rights reserved.