如何在scala

时间:2017-05-14 18:01:26

标签: scala recursion types

假设我有一个A类型。如何在scala中定义B类型Unit或元组(A, B)

我想建模B[A]类型,可以是

(), (A, ()), (A, (A, ())), (A, (A, (A, ()))), (..., (A, (A, (A, ())))). 

我见过像

这样的东西
trait B[A] extends (A, B) {}

中的示例

What does the `#` operator mean in Scala?

但由于缺少终止Unit可能性,因此无法使用我发现的内容。

谢谢。

3 个答案:

答案 0 :(得分:4)

以下内容(类似于List的定义方式):

trait NestedTuple[+A]

case class Tup[A](a: A, tail: NestedTuple[A]) extends NestedTuple[A]
case object End extends NestedTuple[Nothing]

val t1: NestedTuple[Int] = End      
t1: NestedTuple[Int] = End

val t2: NestedTuple[Int] = Tup(1, Tup(2, End)) 
t2: NestedTuple[Int] = Tup(1,Tup(2,End))

答案 1 :(得分:0)

您需要使用密封特性(alegbraic数据类型)来编码类型安全的可能性。

看看无形[1]的HList如何做到这一点..

sealed trait HList
sealed trait HNil extends HList
case object HNil extends HNil
case class ::[+H, +T <: HList](head: H, tail: T) extends HList

@ val xs = 1 :: 2.0 :: "three" :: HNil 
xs: Int :: Double :: String :: HNil = 1 :: 2.0 :: three :: HNil

当你说你需要它是一个元组或一个单元时,那些是extend sealed trait的情况。然后你可以在它们上使用详尽的模式匹配。

[1] https://github.com/milessabin/shapeless

答案 2 :(得分:-1)

它看起来像一个免费的Monad。您可以从scalaz库或cats开始实施。