2009-11-15 51 views
6

我需要返回值,而當有人問一個值,告訴他們的三兩件事之一:斯卡拉:喜歡的東西選項(一些,沒有),但有三種狀態:有的,無,未知

  1. 這裏是價值
  2. 沒有價值
  3. ,我們對此有值(未知)沒有信息

的情況下2比3的情況下舉例微妙的不同:

val radio = car.radioType 
  1. 我們知道值:返回射型,說「先驅」
  2. 灣沒有價值:返回無
  3. c。我們缺少關於這輛車的數據,我們不知道它是否有收音機

我想我可能會擴展scala的None並創建一個Unknown,但這似乎不可能。

意見建議?

謝謝!

更新:

理想情況下,我想能夠寫這樣的代碼:

car.radioType match { 
    case Unknown => 
    case None => 
    case Some(radioType : RadioType) => 
} 

回答

12

這裏是一個準系統實現。你可能想看一下Option類的一些花裏胡哨的來源:

package example 

object App extends Application { 
    val x: TriOption[String] = TriUnknown 

    x match { 
    case TriSome(s) => println("found: " + s) 
    case TriNone => println("none") 
    case TriUnknown => println("unknown") 
    } 
} 

sealed abstract class TriOption[+A] 
final case class TriSome[+A](x: A) extends TriOption[A] 
final case object TriNone extends TriOption[Nothing] 
final case object TriUnknown extends TriOption[Nothing] 
+0

謝謝,這非常有幫助。我最終通過Option實現了類似的東西,其中None和Some作爲已知的子狀態:http://code.alexblack.ca/an-option-class-in-scala-with-three-states-un – 2009-11-18 15:09:42

2

你可以用三種可能創建自己的。或者,您的car.radioType類型可能是未知的,然後在您的案例中使用警衛來處理它。 如果您推出自己的產品,還應包含產品特徵。 liftweb具有Box類型,這是一個選項關閉,允許完整,空白和erorr發生。

+0

滾動我自己的工作 - 我需要它用於許多類型的值,而不僅僅是car.radioType。我看着Lift的盒子,它看起來像它只支持兩個值(Full,Empty):http://scala-tools.org/scaladocs/liftweb/1.0/net/liftweb/util/Box.html – 2009-11-15 17:03:17

+0

I認爲你看錯了。你有一個返回Box的方法。 Box可以是三種繼承類之一,Full,Failure或Empty 如果您按照Option和/或Box作爲模式,也可以使用flatMap,map或forEach。 然後,您可以使用匹配語句來確定它是哪個值。 – 2009-11-16 01:32:47

+0

啊,thx,我明白你現在對Box的意思。 – 2009-11-16 14:41:58

4

您可以使用scala.Either。使用左爲卓越的價值,併爲權預期值可以是在這種情況下,選擇一個選項:

scala> type Result = Either[String, Option[String]] 
defined type alias Result 

scala> val hasValue: Result = Right(Some("pioneer")) 
hasValue: Result = Right(Some(pioneer)) 

scala> val noValue: Result = Right(None) 
noValue: Result = Right(None) 

scala> val unknownValue = Left("unknown") 
unknownValue: Left[java.lang.String,Nothing] = Left(unknown) 
+1

這是一個好主意,但似乎有點冗長。理想情況下,我想寫這樣的代碼:car.radioType match {case Unknown => case None => case Some(radioType:RadioType)=>} – 2009-11-15 17:22:36

5

你可以從Lift:Box中獲取一些東西。它有三種狀態:完整,失敗和空白。另外,Empty和Failure都從EmptyBox繼承。

8

不要告訴任何人我建議這個,但你總是可以使用null爲Unknown,而不是寫一個新的類。

car.radioType match { 
    case null => 
    case None => 
    case Some(radioType : RadioType) => 
} 
+1

這聽起來很簡單,但褻瀆:) – 2009-11-16 14:42:31

0

我不喜歡的東西類似,3類線的劃分在給定的文件,一個給定的線,也許,例如,對於Float爲標題行,Long爲中(行)在一條線上,或String拖車線。也可以使用isHeader,isRowisTrailer來知道哪一個是。希望有幫助:

sealed abstract class HRT[+H, +R, +T] { 
    val isHeader: Boolean 
    val isRow: Boolean 
    val isTrailer: Boolean 
} 

final case class Header[+H, +R, +T](h: H) extends HRT[H, R, T] { 
    override val isHeader: Boolean = true 
    override val isRow: Boolean = false 
    override val isTrailer: Boolean = false 
} 

final case class Row[+H, +R, +T](r: R) extends HRT[H, R, T] { 
    override val isHeader: Boolean = false 
    override val isRow: Boolean = true 
    override val isTrailer: Boolean = false 
} 

final case class Trailer[+H, +R, +T](t: T) extends HRT[H, R, T] { 
    override val isHeader: Boolean = false 
    override val isRow: Boolean = false 
    override val isTrailer: Boolean = true 
} 

object Demo { 
    def getEntries(): Seq[HRT[Float, Long, String]] = 
    List(
     Header(3.14f), 
     Row(42), 
     Trailer("good bye") 
    ) 

    val entries = getEntries() 

    entries.foreach { 
    case Header(f) => printf("header: %f\n", f) 
    case Row(l) => printf("row: %d\n", l) 
    case Trailer(s) => printf("trailer: %s\n", s) 
    } 
} 
相關問題