2017-05-14 4 views
0

Angenommen, ich habe einen Typ A. Wie kann ich einen Typ B in scala definieren, der entweder Unit oder das Tupel (A, B) ist?Wie definiere ich einen bestimmten rekursiven Typ in scala

Ich möchte B[A] eine Art modellieren, die

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

sein kann, ich habe Dinge gesehen, wie

trait B[A] extends (A, B) {} 

oder Beispiele in

What does the `#` operator mean in Scala?

aber war nicht in der Lage arbeite mit dem was ich seit dem Abschlussgefunden habeMöglichkeit fehlt.

Vielen Dank.

+1

'Typ B [A] = Liste [A]' –

Antwort

0

Sie benötigen einen versiegelten Zug (alegbraic Datentyp) zu verwenden, die Möglichkeit, mit Typsicherheit zu kodieren.

Sehen Sie, wie die hList von unförmigen [1] dies tut ..

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 

Wenn Sie sagen, Sie es brauchen entweder ein Tupel oder eine Einheit zu sein, das sind die Fälle, in denen extend die sealed trait. Dann können Sie umfassende Mustererkennung auf ihnen verwenden.

[1]

-1

Es sieht aus wie eine Free Monad. Sie können eine Implementierung von scalaz Bibliothek oder cats nehmen.

+0

Ich denke, es ist eher hList von shapless. Ich sehe nicht, wie es viel mit Freiheit zu tun hat. – Stephen

+1

@Stephen, eigentlich ist es sogar der Typ 'List', da alle Elemente den gleichen Typ haben. –

+0

@CyrilleCorpet, oh richtig. Vielen Dank. – Stephen

4

Wie über die folgende (ähnlich wie List definiert ist):

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)) 
Verwandte Themen