I am trying to extract integer value from a string using Int.fromString
function
but as we know, its specification is : String -> int option
. So the result of applying Int.fromString
is of type int option
. But I need the result of type int
. Also I am sure that the extracted part is integer. How can this be done?

- 2,989
- 2
- 36
- 61
3 Answers
You are free to use SOME
in the left part of expression:
val SOME x = Int.fromString "3";
val x = 3 : int

- 10,179
- 1
- 45
- 53
You can use the valOf
function to get the SOME value of an option:
val i : int = valOf (Int.fromString "1")

- 13,115
- 27
- 76
- 133
-
2This is certainly true and is important to know (so +1), but it is surprising how rarely `valOf` is actually needed. Good code should take the possibility of `NONE` into account, and the natural way to do so is with pattern matching, but then you might as well use a pattern like `SOME x` to extract the value. – John Coleman Apr 10 '16 at 22:24
-
I have noticed a number of cases when an API consumes itself and there is no other case but for this to be valid. That is where I've used it anyway. – eatonphil Apr 11 '16 at 10:24
Like @JohnColeman, I cannot recommend partial functions like
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)
If you must, at least make the error meaningful so you can easily track it down when your supposed invariant breaks because it's only upheld by good will on behalf of the programmer:
fun intFromString s =
case Int.fromString s of
SOME i => i
| NONE => raise Fail ("Could not convert string '" ^ s ^ "' to int!")
The function Int.fromString : string -> int option
is safe, but if you don't like it, you could do:
fun intFromString s default_i =
Option.getOpt (Int.fromString s, default_i)
val intFromString : string -> int -> int
although it should be just as natural to handle NONE
in the calling function, or in a specialized bind operator (>>=
). This comes down to API design, rather than questions safe functions vs. unsafe functions.
If you are certain that an integer can be extracted from the string, why not embed this certainty in a type? E.g. by wrapping these strings in an abstract datatype / module that only allows the production of these certainly convertible strings from within the module. A minimal implementation could be like:
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
At this point I justify the use of valOf
because I know the only way to make a value of type IntString.int_string
is through IntString.fromInt
. The module could be used like:
(* 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)

- 15,635
- 1
- 41
- 66