This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Two fields of two records have same label in OCaml
In Ocaml 3.12.0, is it necessary that any labels of a record have globally unique names?
type foo = { a : int; b : char; }
# type bar = {a : int; b : string};;
type bar = { a : int; b : string; }
# {a=3; b='a'};;
{a=3; b='a'};;
Error: This expression has type char but an expression was expected of type
string
I guess if the record is created anonymously, the only way for the compiler to know which type I'm referring to is the record names. Does declaring bar hide foo?
No, record labels don't have to be globally unique. But they have to be unique in module level.
Declaring bar doesn't hide foo; therefore, type inference is broken when refering to b field.
You can easily create submodules and use module names to distinguish between records with the same label:
module Foo = struct
type foo = {a: int; b: char}
end
module Bar = struct
type bar = {a: int; b: string}
end
let f = {Foo.a = 3; b = 'a'} (* Note that we only need to use module name once *)
let b = {Bar.a = 3; b = "a"}
Related
I am migrating schemas from proto2 to proto3 syntax. I want to eliminate extensions as they are not supported. Is it possible to get an object using a field name in proto3, similar to what MutableExtension does in proto2.
For example,
Schema in proto2 syntax
message Foo {
message Bar {
unint32 a = 1;
}
extend Foo {
Bar b = 1;
}
}
C++
Foo::Bar b_val = foo.MutableExtension(Foo::b);
Now in proto3, I could do this:
syntax="proto3";
message Foo {
message Bar {
unint32 a = 1;
}
Bar b = 1;
}
C++ code:
Foo::Bar b_val = foo.mutable_b();
However, I want to use the name Foo::b to get a Foo::Bar object. Is there a way to do this?
It's not clear why you need this but what you are asking for is kinda feasible.
Foo::b is a garden variety member function, which means that &Foo::b is a regular pointer-to-member-function.
So you can use it as such using the regular c++ syntax for these entities:
auto b_ref = &Foo::b;
Foo::Bar b_val = (foo.*b_ref)();
I'm trying to use the module type Partial_information which is constructed via the functor Make_partial_information as the type of the field contents in the type Cell.t. However, I'm getting the error Unbound module Partial_information.
open Core
(* module which is used as argument to functor *)
module type Partial_type = sig
type t
val merge : old:t -> new_:t -> t
end
(* type of result from functor *)
module type Partial_information = sig
type a
type t = a option
val merge : old:t -> new_:t -> t
val is_nothing : t -> bool
end
(* The functor *)
module Make_partial_information(Wrapping : Partial_type):
(Partial_information with type a = Wrapping.t)
= struct
type a = Wrapping.t
type t = a option
let merge ~(old : t) ~(new_ : t) =
match (old, new_) with
| (None, None) -> None
| (None, Some a) -> Some a
| (Some a, None) -> Some a
| (Some a, Some b) -> (Wrapping.merge ~old:a ~new_:b) |> Some
let is_nothing (it: t) : bool = (is_none it)
end
(* Checking to make sure understanding of functor is correct *)
module Int_partial_type = struct
type t = int
let merge ~old ~new_ = new_ [##warning "-27"]
end
module Int_partial_information = Make_partial_information(Int_partial_type)
(* Trying to use _any_ type which might have been created by the functor as a field in the record *)
module Cell = struct
type id = { name : string ; modifier : int }
type t = {
(* Error is here stating `Unbound module Partial_information` *)
contents : Partial_information.t ;
id : id
}
end
Module types are specifications for modules. They do not define types by themselves. They are also not constructed by functors in any way.
Consequently, it is hard to tell what you are trying to do.
As far I can see, you can simply define your cell type with a functor:
module Cell(P : Partial_information) = struct
type id = { name : string ; modifier : int }
type partial
type t = {
contents : P.t;
id : id
}
end
Or it might be even simpler to make the cell type polymorphic:
type 'a cell = {
contents : 'a;
id : id
}
since the type in itself is not particularly interesting nor really dependent upon
the type of contents.
P.S:
It is possible to use first class modules and GADTs to existentially quantify over a specific implementation of a module type. But it is unclear if it is worthwhile to explode your complexity budget here:
type 'a partial_information = (module Partial_information with type a = 'a)
module Cell = struct
type id = { name : string ; modifier : int }
type t = E: {
contents : 'a ;
partial_information_implementation: 'a partial_information;
id : id
} -> t
end
I am new to SML, trying to explore SML record and types, specifically how to have function inside a record.
For example, I created below type-
type foo={
var1:int,
f1: int -> int // want to have result of function f1 here
};
Now if I declare record of type 'foo'-
val rec1 = { var1= 10, ....}
I am not getting how to populate the 2nd parameter in the record. f1(10) is giving error.Also, can we declare and define the function inside 'type' like below -
type foo ={
var1:int,
f1 (x)=x+x
};
Please share your opinion.
You need to use a function expression:
val r = {var1 = 10, f = fn x => x}
No, you cannot define the value of a record field in a type definition. But you can define a little helper function as a "constructor":
fun new_foo i = {var1 = i, f = fn x => x+x}
def getValueAndItsType() : List[ (AnyRef, Class[_]) ] = {
val dataSet1 = ("some string data", classOf[String])
val dataSet2 = (new Thread(), classOf[Thread])
val dataSet3 = (new NullPointerException(), classOf[NullPointerException])
val dataSet4 = (5, classOf[Int])
val list = List(dataSet1, dataSet2, dataSet3, dataSet4)
list
}
Type type mismatch; found :
List[(Any, Class[_ >: Int with NullPointerException with Thread with
String])] required: List[(AnyRef, Class[_])]
If dataSet4 is removed from List, the compile time error disappears
Please suggest, what is wrong with Class[_]. Isn't it
equivalent to Class[?] in java ? I appreciate, if you also suggest
correct declaration for doing this..
In Scala:
Any is the root of the Scala class.
AnyRef is the root of the class of reference types, it extends from Any.
AnyVal is the root class of all value types. it extends from Any
Null is a subtype of all reference types.
Nothingis a subtype of all other types including Null
So base on your code, you need to extend from Any, include AnyRef: reference types and AnyVal: values types.
def getValueAndItsType() : List[ (Any, _ <: Any) ] = {
val dataSet1 = ("some string data", classOf[String])
val dataSet2 = (new Thread(), classOf[Thread])
val dataSet3 = (new NullPointerException(), classOf[NullPointerException])
val list = List(dataSet1, dataSet2, dataSet3)
list
}
Say I have two distinct types with the same records:
type x = { a : int };;
type y = { a : int };;
Now { a = 5 } will make a type y datum. Is there any way to force it to make a type x datum now?
I am aware that it is possible to wrap each type in a module but I'd like to avoid dealing with modules at this stage. Is there something like { a = 5 } : x that would work?
Heh, I tried { a = 5 } : x first and it didn't work, but just before posting I thought I'd try ({ a = 5 } : x) and apparently that works.