Browse thread
Smells like duck-typing
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Vincent Aravantinos <vincent.aravantinos@y...> |
| Subject: | Re: [Caml-list] Smells like duck-typing |
Le 17 oct. 07 à 15:35, Dario Teixeira a écrit :
> Hi,
>
> I have been trying to reach a sane modelling in OCaml for a "story"
> data structure in a CMS.
(...)
> b) Use only full_t and make all fields option types. However, not
> only is
> this cumbersome to use, but is also conceptually wrong, because
> it does
> not capture the fact that, for example, all "blurb" stories have
> three
> *mandatory* fields.
The following uses polymorphic variants for options so as to make
those fields mandatory (thus it is more safe).
However it remains very cumbersome :)) but I found it interesting
(and quite funny).
And to follow the current topic, this solution makes inheritance the
right way (or, at least, the way you want).
But honestly, I don't think it's usable (?)
--------------
(* TYPES *)
type ('a,'b) polyoption = [<`Some of 'a|`None] as 'b
type 'a string_option = (string,[<`None|`Some of string] as 'a)
polyoption
type 'a int_option = (int,[<`None|`Some of int] as 'a) polyoption
type some_string = [`Some of string]
type some_int = [`Some of int]
type nothing = [`None]
type ('a,'b,'c,'d) t = {
id: 'a int_option;
title: 'b string_option;
intro: 'c string_option;
body: 'd string_option
}
(* The types we will finally use *)
type full_t = (some_int, some_string, some_string, some_string) t
type blurp_t = (some_int, some_string, some_string, nothing ) t
type fresh_t = (nothing , some_string, some_string, some_string) t
(* SOME TESTS *)
let full : full_t = {id = `Some 1; title = `Some "blablax"; intro =
`Some "blox" ; body = `Some "pouetx"}
(* Check with a missing field:
# let badfull : full_t = {id = `None; title = `Some "blablax";
intro = `Some "blox" ; body = `Some "pouetx"};;
This expression has type (...)
*)
let blurp : blurp_t = {id = `Some 2; title = `Some "blablay"; intro =
`Some "bloy" ; body = `None}
(* Check with too much fields:
# let badblurp : blurp_t = {id = `Some 2; title = `Some "blablay";
intro = `Some "bloy" ; body = `Some "pouety"};;
This expression has type (...)
*)
let fresh : fresh_t = {id = `None; title = `Some "blablaz"; intro =
`Some "bloz" ; body = `Some "pouetz"}
(* FUNCTIONS *)
let get_body : ('a,'b,'c,'d) t -> string = fun x -> let `Some x =
x.body in x
let get_title : ('a,'b,'c,'d) t -> string = fun x -> let `Some x =
x.title in x;;
------------------
TESTS:
# get_title full;;
- : string = "blablax"
# get_title blurp;;
- : string = "blablay"
# get_title fresh;;
- : string = "blablaz"
# get_body full;;
- : string = "pouetx"
# get_body blurp;;
This expression has type (...)
# get_body fresh;;
- : string = "pouetz"
Isn't it funny ?
Cheers
Vincent