OCaml: список, который может содержать два типа? - PullRequest
2 голосов
/ 15 сентября 2009

Вместо указания списка int или списка строк, могу ли я указать список, членами которого должны быть либо строки, либо целые числа, но не более?

Ответы [ 2 ]

8 голосов
/ 15 сентября 2009

Вы можете сделать:

type element = IntElement of int | StringElement of string;;

, а затем используйте список element с.

7 голосов
/ 15 сентября 2009

Один из вариантов полиморфный вариант . Вы можете определить тип списка, используя:

# type mylist = [`I of int | `S of string] list ;;
type mylist = [ `I of int | `S of string ] list

Затем определите значения, такие как:

# let r : mylist = [`I 10; `S "hello"; `I 0; `S "world"] ;;
val r : mylist = [`I 10; `S "hello"; `I 0; `S "world"]

Вы должны быть осторожны, чтобы добавлять аннотации типов, потому что полиморфные варианты являются "открытыми" типами. Например, законно следующее:

# let s = [`I 0; `S "foo"; `B true]
val s : [> `B of bool | `I of int | `S of string ] list =
  [`I 0; `S "foo"; `B true]

Чтобы запретить типу списка разрешать нецелочисленные или строковые значения, используйте аннотацию:

# let s : mylist = [`I 0; `S "foo"; `B true];;
This expression has type [> `B of bool ] but is here used with type
  [ `I of int | `S of string ]
The second variant type does not allow tag(s) `B
...