I want to have user-defined type in Ocaml which represents strings which starts with English letter and afterwards can have letters or digits. Is it possible to define such custom type?
Jeffrey Scofield is right: there is no way in OCaml to define a type that would be the subset of strings verifying a given condition. You might however simulate that to some extent with a module and abstract or private data type, as in:
module Ident : sig
type t = private string
val create: string -> t
val (^): t -> t -> t
(* declare, and define below other functions as needed *)
end = struct
type t = string
let create s = (* do some check *) s
let (^) s1 s2 = create (s1 ^ s2)
end;;
Of course, the create
function should check that the first char of s is a letter and the other ones letters or digits and raise an exception if this is not the case, but this is left a an exercise. This way, you know that any s
of type Ident.t
respects the conditions checked in create
: by making the type
synonym private
in the signature, you ensure that you must go through one of the functions of Ident
to create such value. Conversely (s:>string)
is recognized as a string
, hence you can still use all built-in functions over it (but you'll get back string
, not Ident.t
).
Note however that there is particular issue with string
: they are mutable (although that is bound to change in the upcoming 4.02 version), so that you can alter an element of Ident.t
afterwards:
let foo = "x0";;
let bar = Ident.create foo;;
foo.[0] <- '5';;
bar;;
will produce
- : Ident.t = "50"
If you restrict yourself to never modify a string
in place (again this will be the default in the next OCaml's version), this cannot happen.