I'm trying to declare to record types with fields having the same name
but different types.
Something like this:
========================================================================
type ta = { a : int; b : string }
type tb = { a : float; b : string list }
let f v = Printf.printf "%d\n" v.a
========================================================================
Compiler says I have an error in the line with Printf:
This expression has type float but is here used with type int
If I declare type ta second - everything works fine.
Is it a bug? If not, what is an appropriate workaround here?
Thanks in advance.
--
Mykola Stryebkov
Blog: http://mykola.org/blog/
Public key: http://mykola.org/pubkey.txt
fpr: 0226 54EE C1FF 8636 36EF 2AC9 BCE9 CFC7 9CF4 6747
_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs
> Hi,
>
> I'm trying to declare to record types with fields having the same name
> but different types.
> Something like this:
>
> ========================================================================
>
> type ta = { a : int; b : string }
> type tb = { a : float; b : string list }
>
> let f v = Printf.printf "%d\n" v.a
>
> ========================================================================
>
> Compiler says I have an error in the line with Printf:
> This expression has type float but is here used with type int
>
> If I declare type ta second - everything works fine.
> Is it a bug? If not, what is an appropriate workaround here?
>
> Thanks in advance.
No, that is a feature. Just like
let x = 1 in
let x = 2 in
let x = 3 in
Printf.printf "x = %d\n" x
As a workaround you can always put ta and tb into modules. Or you
create wrapper functions (with different names) to create and access
the records before overshadowing tb with ta like this:
type ta = { a : int; b : string }
let ta_make a b = { a = a; b = b; }
let ta_get_a ta = ta.a
let ta_get_b ta = ta.b
type tb = { a : float; b : string list }
let tb_make a b = { a = a; b = b; }
let tb_get_a tb = tb.a
let tb_get_b tb = tb.b
let f v = Printf.printf "%d\n" (ta_get_a v)
The drawback of the wrappers is that you can not match ta with { a =
a; b = b } -> .... So (sub)modules is really the best option if you
want the record fields to keep the same names.
MfG
Goswin
This is not possible with record types (at the same module scope) - when you
declare the second type you obscure the previous type.
<snip>
> If I declare type ta second - everything works fine.
> Is it a bug?
No :o)
> If not, what is an appropriate workaround here?
Either put types ta and tb in separate modules (then you can use qualified
field names) or use different field names. The Unix module in the Standard
Library is a good example of how to do all this in practice - the record
types there all have standard prefixes on the field names.
The other alternative is to use objects but this is heavier in terms of
memory and field access and the type errors messages are more confusing than
with records (but neither of these reasons are necessarily bars to using
them!!).
David
PS Not that it I think it generally offends people on this list, but this
question would have been more appropriate for the Beginners' List -
http://groups.yahoo.com/group/ocaml_beginners