2016-04-10 33 views

回答

2

您可以自由使用SOME在表達式的左側部分:

val SOME x = Int.fromString "3"; 
val x = 3 : int 
+0

謝謝!這是我需要的。 –

2

可以使用valOf函數來獲取選項的某個值:

val i : int = valOf (Int.fromString "1") 
+2

這當然是真實的,並且知道(所以+1)很重要,但令人驚訝的是實際上很少需要'valOf'。好的代碼應該考慮'NONE'的可能性,自然的方式是使用模式匹配,但是你最好使用'SOME x'這樣的模式來提取值。 –

+0

我已經注意到一些API在使用本身並且沒有其他情況但是這是有效的情況。無論如何,這是我用過的地方。 – eatonphil

2

像@JohnColeman,我不能推薦部分功能,如

fun intFromString s = let val SOME i = Int.fromString s in i end 

fun intFromString s = case Int.fromString s of SOME i => i 

fun intFromString s = valOf (Int.fromString s) 

如果你必須至少使誤差有意義的,所以你可以很容易地跟蹤它時,你應該不變的休息,因爲它是由善意代表程序員的唯一堅持:

fun intFromString s = 
    case Int.fromString s of 
     SOME i => i 
     | NONE => raise Fail ("Could not convert string '"^s^"' to int!") 

功能Int.fromString : string -> int option是安全的,但如果你不喜歡的話,你可以這樣做:

fun intFromString s default_i = 
    Option.getOpt (Int.fromString s, default_i) 

val intFromString : string -> int -> int 

儘管它應該是一樣自然在調用函數來處理NONE,或者在專門綁定運營商(>>=)。這歸結於API設計,而不是質疑安全功能與不安全功能。

如果你確定可以從字符串中提取整數,爲什麼不把這個確定性嵌入到一個類型中呢?例如。通過將這些字符串包裝在一個抽象的數據類型/模塊中,只允許從模塊中生成這些可以轉換的字符串。一個最小的實現可以是這樣的:

signature INT_STRING = 
sig 
    type int_string 
    val fromInt : int -> int_string 
    val toInt : int_string -> int 
    val lift : (string -> 'a) -> (int_string -> 'a) 
end 

structure IntString :> INT_STRING = 
struct 
    type int_string = string 
    fun fromInt i = 
     if (i < 0) 
     then "-"^Int.toString (Int.abs i) 
     else Int.toString i 

    fun toInt s = 
     if String.sub (s, 0) = #"-" 
     then ~ (valOf (Int.fromString (String.extract (s, 1, NONE)))) 
     else valOf (Int.fromString s) 

    fun lift f s = f s 
end 

在這一點上我證明使用valOf,因爲我知道做類型的值IntString.int_string是通過IntString.fromInt的唯一途徑。該模塊可用於:

(* This property can be tested for arbitrary inputs i. *) 
val id_prop i = IntString.toInt (IntString.fromInt i) = i 
val test1 = id_prop 123 
val test2 = id_prop ~55 
val test3 = id_prop 0 

(* Some standard string functions work just as well. *) 
val intStringSize = IntString.lift String.size 
val intStringPrint = IntString.lift String.print 

val test4 = intStringSize (IntString.fromInt 555) = 3 
val _ = intStringPrint (IntString.fromInt 12345) 
+0

謝謝@SimonShine。這個想法很酷。 –