2016-04-10 42 views
2

Int.fromString関数 を使用して文字列から整数値を抽出しようとしていますが、われわれの仕様はString -> int optionです。したがって、Int.fromStringの適用結果はint optionです。しかし、タイプintの結果が必要です。また、抽出された部分が整数であると確信しています。これはどうすればできますか?SMLで文字列をintに変換する方法(intオプションではなく)

答えて

2

あなたは、式の左部分にSOMEを自由に使用することが:

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

ありがとう!それは私が必要なものです。 –

2

あなたはオプションのSOME値を取得する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設計に帰着します。

文字列から整数を抽出できることが確実な場合は、この確信度を型に埋め込むことをおすすめします。例えば。これらの文字列を抽象データ型/モジュールにラップすることで、モジュール内からこれらの確かに変換可能な文字列を生成することができます。私はタイプIntString.int_stringの値を作成する唯一の方法はIntString.fromIntている知っているので、私はvalOfの使用を正当化する。この時点で

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 

:最小限の実装は次のようである可能性があります。モジュールは次のように使用できます:

(* 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ありがとうございました。アイデアはクールです。 –

関連する問題