I have a question about using a local function in a global function.
I tried to write the function which appears in the picture, but an error said
unbound value of f
It's strange that this error occurs. It should not appear because I defined the definition of the function enf in affichage.
Here is a picture of a relevant part of my code:
What can be the reason of this error?
enf is not defined when affichage is defined, so since the body of affichage refers to enf, this results in an unbound value error. In order to have mutually recursive functions, you'll need something of the form
let rec affichage (* ... *) =
(* ... *)
and enf (* ... *) =
(* ... *)
in
(* ... *)
;;
Related
I'm trying to learn C++ at my own pace via an online course. There is a function declaration and also there is an integer declaration just after that, which is q.
I don't understand what purpose the "q" serves in the code.
I tried to print out each step and it didn't make sense. I literally don't see the point of having a "q" in the foo function or what it does.
#include<stdio.h>
int foo (int q) {
int x = 1;
return (q + x);
}
int main (){
int x = 0;
while (x < 3) {
printf ("%i\n", x);
x = x + foo(x);
}
}
This code gives me
0
1
Seems like the "q" is incrementing x but I don't see the reason why because we didn't assign it to anything but just saying (int q)
In the code you posted, q is an argument to the function foo and foo will return the value of its argument (q) +1.
It is a call by value function call where foo() get call by passing the value to q variable.
If you not declare any argument in the function it will give an error because it's int q only to get the value from the main function.
So here when first time foo get call - it's return 1 and after that it's return 2 .
So in second time x=1+2=3
3>3 condition false.
It print only 0,1.
q is a parameter. That is, it is something in a function that accepts a value from the caller. As w3schools puts it:
Information can be passed to functions as a parameter. Parameters act as variables inside the function.
Parameters are specified after the function name, inside the parentheses. You can add as many parameters as you want, just separate them with a comma:
Probably couldn't have explained it better myself.
This code gives me 0 1 Seems like the "q" is incrementing x but I don't see the reason why because we didn't assign it to anything but just saying (int q)
Ah, so, we actually did assign it to something. It might just not be noticeable. We did it when we called foo:
x = x + foo(x);
Here, by putting x between the parenthesis, we set q to the value of x (which appears to be 0, in this case). That means, q will have the value of x (0) inside the function call.
We also could have set it to something else, like 3:
x = x + foo(3);
Here, q is set to 3, because 3 is inside the parenthesis.
int foo (int q)
declares a function that takes an input parameter, q. The value q takes, in foo, depends on the value that is passed to it. In this case, when you call it with:
foo(x)
You state: run the code in foo, but give to q, upon entering the function, the value of x in main(). When you start programming, at first, this is misleading as q and x appear to be different variable. You'll get used to it.
You must also realise that the x in foo has nothing to do with the x in main. Those are different variables.
Thank you for all your answers and comments.
It seems like the q is the argument passed in and x is just there for representing an integer (redundantly).
It'd have been better if the code just used the integer 1 as:
int foo (int q) {
return (q + 1);
I am new to OCaml and I am trying use functors. When I use the module type annotations with the functors, this results in a compile time error in my code.
When I remove the : Printable (from the module FromToString line) and the : ToString (from the module IntToString line) annotations, the following program compiles without error:
module type ToString =
sig
type t
val to_string: t -> string
end
module type Printable =
sig
type t
val print: t -> unit
end
module FromToString (S:ToString) : Printable =
struct
type t = S.t
let print a = print_string ( S.to_string a)
end
module IntToString : ToString =
struct
type t = int
let to_string = string_of_int
end
module PrintableInt = FromToString(IntToString)
let () = PrintableInt.print 3
However, when I add these annotations (as shown in the code) the compiler gives the following error:
File "Functor.ml", line 26, characters 28-29:
Error: This expression has type int but an expression was expected of type
PrintableInt.t = FromToString(IntToString).t
How can I use these annotations without causing a compile error?
The root issue is that your signature constraints make the resulting module far too opaque. When you constrain your functor result:
module FromToString (S:ToString) : Printable = ...
you are making the type t an abstract type, which can only be consumed by the to_string function and never been produced. In other words, a module of type Printable is unusable by itself.
When starting with functor, it is very often useful to look at the module type inferred by the compiler for the resulting module.
In the FromToString case, this is:
module FromToString (S:ToString) : sig
type t = S.t
val print: t -> unit
end = ...
You can see that the inferred module type of the result
sig
type t = S.t
val print: t -> unit
end
that it is quite similar to Printable except that now the type t is equal to the type t of the argument module S.
Thus, it is possible to reuse Printable to write the full module type of the result by adding a type equality with a with constraint:
module FromToString (S:ToString): Printable with type t = S.t = struct
type t = S.t
let print a = print_string ( S.to_string a)
end
The same issue appears for IntToString and can be fixed in a similar way:
module IntToString : ToString with type t = int =
struct
type t = int
let to_string = string_of_int
end
Then the compiler error is gone:
module PrintableInt = FromToString(IntToString)
let () = PrintableInt.print 3
One has to make the type t public, using the with notation:
module type ToString =
sig
type t
val to_string: t -> string
end
module type Printable =
sig
type t
val print: t -> unit
end
module FromToString (S:ToString) : Printable with type t = S.t =
struct
type t = S.t
let print a = print_string ( S.to_string a)
end
module IntToString : ToString with type t =int =
struct
type t = int
let to_string = string_of_int
end
module PrintableInt = FromToString(IntToString)
let () = PrintableInt.print 3
Let's say I had a simple module MyFoo that looks something like this
module MyFoo = struct
type t =
| A of string
| B of int
let to_string thing =
match thing with
| A str -> str
| B n -> string_of_int n
end
With this definition, it works great and as expected — I can do something like
let _ = MyFoo.A "";;
- : MyFoo.t = MyFoo.A ""
without any problems.
Now maybe I want to create a functor that consumes modules with this structure, so I define a module signature that describes generally what this looks like and call it BaseFoo
module type BaseFoo = sig
type t
val to_string : t -> string
end
If I redefine MyFoo the same way but giving it this signature like
module MyFoo : BaseFoo = struct
type t =
| A of string
| B of int
let to_string thing =
match thing with
| A str -> str
| B n -> string_of_int n
end
I lose the precision of its type t (is there a better way to describe what happens here?) — for example:
let _ = MyFoo.A "";;
Error: Unbound constructor MyFoo.A
What exactly is going on here and why does it happen? Is there a canonical way for dealing with this kind of problem (besides just leaving off the signature)?
I've tried manually including the signature and the specific type type definition too but get a different kind of error (this probably isn't the right approach).
module MyFoo : sig
include BaseFoo
type t = | A of string | B of int
end = struct
type t =
| A of string
| B of int
let to_string thing =
match thing with
| A str -> str
| B n -> string_of_int n
end
let _ = MyFoo.A "test";;
Error: Multiple definition of the type name t.
Names must be unique in a given structure or signature.
You don't need the signature
What is going on is pretty much what you describe: giving MyFoo the BaseFoo signature in its definition restricts it to the signature.
Why? Because this is what specifying a signature at this place is for. The canonical solution is to leave of the signature (usually, letting the signature definition next to the module definition will be clear enough for the reader).
Note that when you call MyFoo on your functor, the signature will be checked. My usual choice is to rely on that.
A few workarounds
Given what you've tried, I guess this could be interesting to you:
module type BaseFoo = sig ... end
module MyFoo = struct ... end
module MyFooHidden : BaseFoo = MyFoo (* Same as defining MyFoo : BaseFoo *)
module MyFooWithType :
BaseFoo with type t = MyFoo.t
= MyFoo (* What you want *)
The with type t = t' clause allows you to annotate a module signature to add type information to it. It is quite useful, especially when dealing with functors. See here for more information.
MyFooHidden may seem useless, but you can see it as a check that MyFoo has the right signature. You can still use MyFoo however you want after all. MyFooWithType is actually (a bit) less useful because if you change your signature to add a type you'd want exported, you'd need to add the export here too.
Using include
As for your include try. Well, nice try! You were almost there:
module MyFoo : sig
type t = A of string | B of int
include BaseFoo with type t := t
end
The with type t := t' is a bit different in that it doesn't perform an equality but a replacement. The type t definition is removed from the BaseFoo signature altogether and all instances are replaced with your own t, that way you don't get any double definition problem. See here for more details.
As you point out, this is probably not the approach you want, as you no longer easily know that MyFoo is indeed a BaseFoo.
In Rascal, say I have the code:
value x = 2;
data Exp = con(int n);
Is there a way to call con(x), while x is a value (but actually an integer), without knowing on beforehand what the type of con's first argument is supposed to be (thus without explicitly casting it to an int)?
Why is it possible to call a function, say int something(int n) = n, with an integer defined as a value (e.g. value y = 2) passed into its first argument, while it gives me an error when I try to do the same with user-defined ADTs?
When you call a function in Rascal it actually is doing a pattern match on the arguments. So, if you define int something(int n) = n;, and then call something(x), it matches x with int n, sees that x is actually an int (so it can bind the value to n), and calls the function.
If you were to define value x = 2.5 instead and then call something(x) you would get an error since it cannot bind the value 2.5 to int n. You could overload something with a second definition that takes a real instead, like int something(real r) = toInt(r);, and it would then work. Two items to note here, though: something needs to return the same type in both cases, and you need to import util::Math to get access to toInt.
When you are using a constructor, like con(x), it doesn't do a pattern match for you automatically. The type that you give it has to match the type it expects. If you know that x will always be an int, it would be best to just declare it as such. Another option would be to create a function like Exp makeCon(int n) = con(n); which you could then use as you would like, i.e., Exp myExp = makeCon(x);. It would be best in this case to include a default version of the function, just in case you give it something unexpected, like default Exp makeCon(value x) { throw "Unexpected value <x>"; }, this way if you ever try to create a con with something that isn't an int you will get an error that you can handle, with the ability to create your own error message, add additional error handling versus just showing a message, see the value causing the problem, etc, versus just having the interpreter give an error (which may not give you all the info you want).
I want to have a big functor Hello(Blah: Blah_type) and save it in the file hello.ml, but how do I do this?
If I was just in my top level file, I'd have
module Hello(Blah: Blah_type) =
struct
val x = 2
end
but how do I put the argument in hello.ml? I can't just have the whole file being "val x = 2" ... ?
OCamlPro has a compiler patch and external tool which may support this:
http://www.ocamlpro.com/blog/2011/08/10/ocaml-pack-functors.html
As far as I know the official compiler release does not support .ml files as functors.
It is not possible. Source files are always represented as ordinary modules, not functors. This is trivially solved with one extra open.
To complement ygrek's answer with a real code sample, instead of a file foo.ml with content
module type S = sig
(* ... *)
end
module Hello (M : S) = struct
(* ... *)
end
module M : S = struct
(* ... *)
end
module H = Hello(M)
(* ... *)
You could have hello.ml with content
module type S = sig
(* ... *)
end
module Make (M : S) = struct
(* ... *)
end
and foo.ml rewritten as
module M : Hello.S = struct
(* ... *)
end
module H = Hello.Make(M)
(* ... *)
PS: In case you find it confusing, the module sealing M : S or M : Hello.S is optional (M will be coerced to this signature when passed to the functor anyway), it was just to show how this can be done.