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

Kev*_*ith 6 haskell scala

在Scala中,我可以定义代数数据类型:

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
Run Code Online (Sandbox Code Playgroud)

可以返回一个函数,f返回类型为Maybe[A].

scala> def f[A](x: A): Maybe[A] = Just(x)
f: [A](x: A)Maybe[A]
Run Code Online (Sandbox Code Playgroud)

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

scala> def f[A](x: A): Just[A] = Just(x)
f: [A](x: A)Just[A]
Run Code Online (Sandbox Code Playgroud)

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

Prelude> data Option a = None | Some a deriving Show
Prelude> let f x = Some x :: Option Int
Prelude> f 10
Some 10
Run Code Online (Sandbox Code Playgroud)

但是,我无法设置类型构造函数的返回类型.

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
Run Code Online (Sandbox Code Playgroud)

Scala Just是一个类的简单区别,即合法的返回类型吗?然而,在Haskell中,类型构造函数不能是返回类型?

bhe*_*ilr 10

不同之处在于Scala如何选择实施ADT.Scala使用以OOP样式扩展特征的case类,因此每个case都是它自己的类型,而Haskell只有多个相同类型的构造函数.由于它们不是单独的类型,而是基本上只是单独的函数,因此您无法在类型级别区分它们.有一些扩展可以让你有一些能够进行类型级别区分的扩展,但它与Scala所具有的不同.试图将Haskell的类型系统融入Scala的类型系统可能不是最好的想法.

简而言之,Scala使用一种继承形式来近似ADT,而Haskell只有ADT.

  • 有一些扩展可以提供_similar_ ability,但是Haskell没有子类化是非常重要的,所以你肯定不能做_同样的事情_ .. (3认同)