Shorthand for constructor function - ocaml

Is there any way to pass a constructor as a function?
type foo =
| Foo of int
| Bar of int
let foo x = Foo x
let bar = fun x -> Bar x
Is there any shorthand for the functions foo and bar? I want to pass a constructor as a function, but it seems unwieldy to write fun x -> Bar x.

camlspotter's answer was close enough, but in your case you want to use Variantslib and add with variants at the end of your type definition:
type foo = Foo of int | Bar of int with variants;;
gives you the following:
type foo = Foo of int | Bar of int
val bar : int -> foo = <fun>
val foo : int -> foo = <fun>
module Variants :
sig
val bar : (int -> foo) Variantslib.Variant.t
val foo : (int -> foo) Variantslib.Variant.t
end

Use Fieldslib: https://github.com/janestreet/fieldslib .
Adding with fields postfix at the type definition like:
type foo = | Foo of int | Bar of int with fields
and compile it with Fieldslib's syntax extension. It automatically generates foo and bar for you.

You can now use ppx_variants_conv, like this:
type 'a t =
| A of 'a
| B of char
| C
| D of int * int
[##deriving variants]

Related

Parametrized module types

I am trying to build a hierarchy of module types which depend on each other. In Coq I can write something like this:
Module Type Foo.
Parameter t:Type.
End Foo.
Module Type Bar1 (T:Foo).
Parameter f1: T.t -> T.t.
End Bar1.
Module Type Bar2 (T:Foo).
Parameter f2: T.t -> T.t.
End Bar2.
Module Ex (F:Foo) (B1: Bar1 F) (B2:Bar2 F).
End Ex.
How would I express it in OCaml?
Unfortunately, Ocaml does not directly support parameterised module types. However, you can emulate them by wrapping a parameterised module around them:
module type Foo =
sig
type t
end
module Bar (X : Foo) =
struct
module type T =
sig
val f : X.t -> X.t
end
end
module Ex (F : Foo) (B : Bar(F).T) = ...
A bit more clumsy, but has the same effect.
To elaborate on gsg's answer, if you have a more complex Foo module type, you can use with module instead of with type, and have a module specification in both Bar types, as in the following example:
module type Foo =
sig
type t
end
module type Bar1 = sig
module F: Foo
val f1: F.t -> F.t
end
module type Bar2 = sig
module F: Foo
val f2: F.t -> F.t
end
module Ex (F: Foo) (B1: Bar1 with module F = F) (B2: Bar2 with module F = F) =
struct
let f3 x = B2.f2 (B1.f1 x)
end
module Bar1_impl (F: Foo): Bar1 with module F = F = struct
module F = F
let f1 x = x
end
module Bar2_impl (F: Foo): Bar2 with module F = F = struct
module F = F
let f2 x = x
end
module F: Foo with type t = int = struct type t = int end
module M = Ex(F)(Bar1_impl(F))(Bar2_impl(F))
let x = M.f3 0;;
Module types do not take arguments. However, this particular pattern can be expressed by with type:
module type FOO = sig
type t
end
module type BAR1 = sig
type t
val f1 : t -> t
end
module type BAR2 = sig
type t
val f2 : t -> t
end
module Ex (F:FOO) (B1 : BAR1 with type t = F.t) (B1 : BAR2 with type t = F.t) = struct
end

The difference between environments in definition time and environments in application time

I have this code in Standard ML and I want to know what environments and what bindings are created at definition and at application time, and what's the difference between the both.
fun boo boo =
let
type boo = int
val boo : boo = boo
val boo : { boo : boo } = { boo = boo }
in
# boo boo
end
I searched but could not come with an accurate answer,
Thanks in advance.
I'm still somewhat new to SML, but I think I've got this:
fun boo boo (* 1 *) =
let
type boo (* 2 *) = int
val boo (* 3 *) : boo = boo (* 1 *)
val boo (* 4 *) : { boo (* 5 *) : boo } = { boo = boo } (* 6 *)
in
# boo boo (* 7 *)
end
I labeled each boo to keep track of them. They are:
A free parameter (to the function 'boo') of type int
A type, aliased to type int
A new value of type boo (int) which is bound to the parameter passed to the function
A record value...
with field 'boo' of type boo (int)...
that's assigned the "new" boo value from (3)
projection of field 'boo' from record 'boo' (has type 'boo' (int))
The overall function has type : int -> int

operator() overload and c'tor ambiguity in function objects

assuming we have the next function object:
class foo{
private:
int counter;
public:
foo(int counter): counter(counter){}
foo& operator=(const foo& ){...}
bool operator() (int variable){....}
}
int main(){
foo f(4);
foo x(5);
x = f(4);
return 0;
}
how does the compiler knows how to respond to:
x = f(5)?
I've been searching for a while on the web and in Stack and haven't found exact answer, if its a repost , tell me and i'll delete the question.
It depends on whether the "(5)" is being used to construct an object or called on an already-existing object:
foo f(5); // calls the constructor
f(5); // calls operator()
I added a simple method called eval to explain it:
class foo {
private:
int counter;
public:
foo(int counter): counter(counter) {}
bool operator() (int variable) {
return variable < counter;
}
bool eval(int variable) {
return variable < counter;
}
};
foo is a class not a method.
an instance of foo can be used like a method.
calling foo(5) will create an instance of foo where the counter = 5.
eval is a member function of foo. (for now this will do the same as the () operator)
You can call eval like this:
foo f = foo(5); // create an instance of `foo`
f.eval(3); // returns true -> 3 < 5
f.eval(0); // returns false -> 6 < 5
You can also use the () operator:
foo f = foo(5); // create an instance of `foo`
f(3); // returns true -> 3 < 5
f(0); // returns false -> 6 < 5
NOTE:
You can also write (but don't do it):
foo f = foo(5); // create an instance of `foo`
f.operator()(3); // returns true -> 3 < 5
f.operator()(0); // returns false -> 6 < 5

C++ When do I use -> or ::

I know that in C++, you use either -> or :: instead of . in language such as C# to access object's values, e.g. button->Text or System::String^, but I don't know when I should use -> or ::, and it is very frustrating as it causes me many compiler errors. I would be very grateful if you could help. Thanks :)
-> is when you are accessing the member of a pointer variable. EG: myclass *m = new myclass(); m->myfunc(); Calls myfunc() on pointer to myclass. :: is the scoping operator. This is to show what scope something is in. So if myclass is in namespace foo then you'd write foo::myclass mc;
-> if you have pointer to some object this is just shortcut for dereferencing that pointer and accessing its attribute.
pointerToObject->member is the same as (*pointerToObject).member
:: Is for access stuff from some scope - it works only on namespaces and class/struct scopes.
namespace MyNamespace {
typedef int MyInt;
}
MyNamespace::MyInt variable;
Contrary to what your question states, you do use . in C++. Quite a bit.
. (used with non-pointers to access members and methods)
std::string hello = "Hello";
if (hello.length() > 3) { ... }
-> (used with pointers to access members and methods)
MyClass *myObject = new MyClass;
if (myObject->property)
myObject->method();
:: (scope resolution)
void MyClass::method() { ... } //Define method outside of class body
MyClass::static_property; //access static properties / methods
:: is also used for namespace resolution (see first example, std::string, where string is in the namespace std).
I try to show an examples of some usages of ::, . and ->. I hope it helps:
int g;
namespace test
{
struct Test
{
int x;
static void func();
};
void Test:: func() {
int g = ::g;
}
}
int main() {
test::Test v;
test::Test *p = &v;
v.x = 1;
v.func();
p->x = 2;
p->func();
test::Test::func();
}
Opertor -> is applied when the left operand is a pointer. Consider for example
struct A
{
int a, b;
A( int a, int b ) : a( a ), b( this->a * b ) {}
};
Operator :: referes to the class or anmespace for which the right operand belongs. For example
int a;
strunt A
{
int a;
A( int a ) { A::a = a + ::a; }
};
The period is used then the left operand is lvalue of an object. For example
struct A
{
int x;
int y;
};
A *a = new A;
a->x = 10;
( *a ).y = 20;

Is it a legal notation: Foo &foo = Bar;

struct Foo {};
struct Bar : Foo {};
Foo &foo = Bar; // without ()
I wonder, Is it a legal notation? And if it is legal, could you give some details? Something like, Why it's legal? Or, What is the origin of such a notation?
EDIT: I cannot compile this code. But I met a code like that and wanted to know whether such a notation is allowed (probably just my compiler doesn't support this notation). I'm having some uncertainty since the following notation is quite legal: Foo *pFoo = new Bar;
It should be a compiler error.
g++: error: expected primary-expression before ';' token
Bar is a name of class and it cannot be assigned to reference / variable. Even with putting () it will not compile, unless you make foo a const Foo&.
You cannot assign an class Name to a reference/object. It is neither syntactically valid nor does it make any sense.
You cannot bind a reference to a temporary(rvalue), So following is illegal too:
Foo &foo = Bar();
You can bind a temporary(rvalue) to an const reference, So following is legal:
const Foo &foo = Bar();
The C++ standard specifically allows the 3.
The code as presented is not legal because Bar is the name of a class, not a variable.
The following, however, is:
struct Foo {}
struct Bar : Foo {}
Bar fooBar;
Foo &foo = fooBar; // without ()
It is legal because Bar is a Foo, so you're just giving a different name to your variable fooBar.
Note however that foo, although an alias for fooBar, will interpret the location as a Foo object.
This means the following:
struct Foo { int x; }; //note semicolons after struct declaration
struct Bar : Foo { int y; };
Bar fooBar;
fooBar.y = 2;
fooBar.x = 3;
Foo &foo = fooBar;
int aux;
aux = foo.x; // aux == 3
aux = foo.y; // compile error
You can't assign a value to a reference. So as already mentioned this is not legal regardless of the parentheses.