I have a task to do in ocaml and can't find any help information so ask here ;) How to define function which give us something other in each call without using global variables ? I would like to do fun next() which return next odd numbers or next values of factorial.
Like this
# next();;
- : int = 1
# next();;
- : int = 3
# next();;
- : int = 5
# next();;
- : int = 7
Do you have any tips for me ?
Thanks in advance
Greg
let next =
let private_counter = ref (-1) in
fun () ->
private_counter := !private_counter + 2;
!private_counter
You can also encapsulate this in a "counter factory":
let make_counter () =
(* note the () parameter : at each call of make_counter(),
a new "next function" with a fresh counter is generated *)
let private_counter = ...
Related
I'm trying to make a type that should represent a "slice" of some indexable collection.
I know that there are some similar types in F# but not one that specifies the criteria that I need.
To do this it needs to carry a reference to the collection of type 'content and the content needs to be indexable. So I tried this constraint since a type only needs to have the member Item (get/set) so I tried this
type Slice<'a, 'content when 'content: (member Item: int -> 'a)>
This still throw the usual error
So is it possible to constrain a type to still be generic but constraint to be indexable?
I think something like this should work:
type Slice<'a, 'content when 'content: (member get_Item: int -> 'a)> =
{
Content : 'content
Start : int
Stop : int
}
with
member inline slice.get_Item(i) =
slice.Content.get_Item(slice.Start + i)
I've implemented get_Item on Slice as well, so you can take a slice of a slice. Here are some values of this type:
let strSlice =
{
Content = "hello"
Start = 1
Stop = 2
}
let arraySlice =
{
Content = [| 2; 4; 6; 8 |]
Start = 0
Stop = 3
}
let strSliceSlice =
{
Content = strSlice
Start = 0
Stop = 1
}
[<Interface>]
type Indexable<'a> =
abstract member Item: int -> 'a with get
[<Struct>]
type Slice<'a> =
{
content: Indexable<'a>
start: int
len: int
}
with
interface Indexable<'a> with
member I.Item with get(i) = I.[idx]
member S.Item with get(idx) =
if idx >= S.len
then raise(IndexOutOfRangeException())
else S.content.[S.start+idx]
This works.
I am trying to define a Point module that defines a type to represent 2d points.
I would also like to include a submodule Point.Set so that Point.Set.t is
a type meaning 'a set of Points'. That seems logical and convenient, but I am not able to figure out how to make the 'circular' reference that this involves.
I tried this:
file: point.ml (implicitly defines a 'Point' module)
type t = {x: int; y:int}
let compare {x=x1;y=y1} {x=x2;y=y2} = ...implementation omitted for brevity...
module Set = Stdlib.Set.Make(Point)
(* ^^^^^ Internal path Mylib__Point is dangling *)
When I dune build the Mylib project/library this is in. I get an error:
Internal path Mylib__Point is dangling.
The compiled interface for module Mylib__Point was not found.
I am not entirely sure what the error really means, but I gather it probably has something to do with the fact that we are trying to reference the Point module from within itself. And maybe that is not allowed?
I can work around this by instead defining a separate 'pointSet.ml' file and in there have include Set.Make(Point). Now I have a module called PointSet. That is okay, but I still would find it a bit more 'aesthetically pleasing' if Point.Set could be a submodule of Point instead. Is there a way to make this work?
If you don't mind a little bit of boilerplate, I think this solution may suit you:
point.ml
module Point = struct
type t = { x : int; y : int }
let compare { x = x1; y = _y1 } { x = x2; y = _y2 } = x1 - x2
end
module Set : Set.S with type elt = Point.t = Set.Make (Point)
include Point
You'll have access to Point.Set and since point.ml includes the module Point at the end of the file, you won't have to do Point.Point.compare ... in other files.
[EDIT]
I previously made the modules mutually recursive but in this case it's useless. If you need them to be mutually recursive you'll have to explicit their signatures:
point.ml
module rec Point : sig
type t
val compare : t -> t -> int
end = struct
type t = { x : int; y : int }
let compare { x = x1; y = _y1 } { x = x2; y = _y2 } = x1 - x2
end
and Set : (Stdlib.Set.S with type elt = Point.t) = Stdlib.Set.Make (Point)
include Point
As far as I know a module doesn't have a name for itself. You can make a module (a struct) just for the purpose of supplying it to the functor Set.Make:
type t = { x : int; y : int }
let compare a b = compare a b
module Set =
Set.Make(struct type nonrec t = t let compare = compare end)
It would be a basic question, but I couldn't figure out a solution. I need to initialize a constant out of the right-side value of below either type.
val test: Either<String, Int> = 1.right()
I tried something like below but it shrinks the scope of the constant.
when(test) {
is Either.Right -> {val get:Int = test.b}
is Either.Left -> println(test.a)
}
I want that get to be scoped outside of when statement. Is there any way to do it or Arrow Either is not made for this purpose?
The important question is: what should happen if the Either is Left. In this example it is created close to where it's used, so it is obvious to you as a developer. But to the compiler what is inside the Either can be either an Int or a String.
You can extract the value using for example fold:
val x = test.fold({ 0 }, {it}) // provide 0 as default in case the Either was a `Left`
// x = 1
another option is getOrElse
val test = 1.right()
val x = test.getOrElse { 42 } // again, default in case it was a `Left`
// x = 42
You can also work with it without unwrapping it:
val test = 1.right()
val testPlus10 = test.map { it + 10 } // adds 10 to `test` if it is `Right`, does nothing otherwise
val x = testPlus10.getOrElse { 0 } // unwrap by providing a default value
// x = 11
For more example check the official docs.
Recommended reading: How do I get the value out of my Monad
I'd like to extend a module but I need access to its private components. Here's an example:
nat.mli:
type t
val zero : t
val succ : t -> t
nat.ml:
type t = int
let zero = 0
let succ x = x + 1
I'd like to define a new module Ext_nat that defines a double function. I was trying to do something like this.
ext_nat.mli:
include (module type of Nat)
val double : t -> t
ext_nat.ml:
include Nat
let double x = 2 * x
It's not working as I don't have access to the representation of x in the last line.
Now that I'm thinking about this, it may not be such a good idea anyway because this would break the encapsulation of nat. So what is the best way to do this? I could define a new module nat_public where type t = int in the signature, and define nat and ext_nat with a private type t. What do you think?
You need to use with type statement. It is possible to write the code below in many different ways, but the idea is always the same.
module type NatSig =
sig
type t
val zero : t
val succ : t -> t
end
module type ExtNatSig =
sig
include NatSig
val double : t -> t
end
module ExtNat : ExtNatSig =
struct
type t = int
let zero = 0
let succ = fun x -> x + 1
let double = fun x -> x * 2
end
module Nat = (ExtNat : NatSig with type t = ExtNat.t)
let z = Nat.zero
let _ = ExtNat.double z
The problem is that as far as I remember it's impossible to achieve this behavior with your file structure: you define your module implicitly with signature in .mli file and structure itself in .ml, so you don't have enough control over you module, that's why I suggest you to reorganize your code a little bit (if it's not a problem).
I have a recursive function fact, which can be called from either an expression inside it or an expression outside it.
I would like to associate fact with a variable v, such that each time fact is called from outside (another function), v is initialized, and its value can be changed inside fact, but never can be initialized when fact is called from inside.
The following code suits my need, but one problem is that v is defined as a global variable, and I have to do v := init before calling fact from outside, which I do not find beautiful.
let init = 100
let v = ref init
let rec fact (n: int) : int =
v := !v + 1;
if n <= 0 then 1 else n * fact (n - 1)
let rec fib (n: int) : int =
if n <= 0 then 0
else if n = 1 then (v := !v + 50; 1)
else fib (n-1) + fib (n-2)
let main =
v := init;
print_int (fact 3);
print_int !v; (* 104 is expected *)
v := init;
print_int (fib 3);
print_int !v;; (* 200 is expected *)
Could anyone think of a better implementation?
You can hide the function and value definitions within the body of a containing function as follows:
open Printf
let init = 100
let fact n =
let rec fact counter n =
incr counter;
if n <= 0 then 1 else n * fact counter (n - 1)
in
let counter = ref init in
let result = fact counter n in
(result, !counter)
let main () =
let x, count = fact 3 in
printf "%i\n" x;
printf "counter: %i\n" count (* 104 is expected *)
let () = main ()
You can adapt Martin's solution so that data is shared across various calls:
let fact =
let counter = ref 0 in
fun n ->
let rec fact = ... in
fact n
The idea is to transform let fact = fun n -> let counter = ... in ... into let fact = let counter = ... in fun n -> ...: counter is initialized once, instead of at each call of fact.
A classical example of this style is:
let counter =
let count = ref (-1) in
fun () ->
incr count;
!count
Beware however that you may get into typing trouble if the function was meant to be polymorphic: let foo = fun n -> ... is always generalized into a polymorphic function, let foo = (let x = ref ... in fun n -> ...) is not, as that would be unsound, so foo won't have a polymorphic type.
You can even generalize the counter example above to a counter factory:
let make_counter () =
let count = ref (-1) in
fun () ->
incr count;
!count
For each call to make_counter (), you get a new counter, that is a function that shares state across call, but whose state is independent from previous make_counter () counter creations.
With Ocaml's objects, you can do:
class type fact_counter = object ('self)
method get : int
method set : int -> unit
method inc : unit
method fact : int -> int
end;;
class myCounter init : fact_counter = object (self)
val mutable count = init
method get = count
method set n = count <- n
method inc = count <- count + 1
method fact n =
self#inc;
if n <= 0 then 1 else n * self#fact (n - 1)
end;;
Then you can obtain:
# let c = new myCounter 0;;
val c : myCounter = <obj>
# c#fact 10;;
- : int = 3628800
# c#get;;
- : int = 11
# c#set 42;;
- : unit = ()
# c#fact 10;;
- : int = 3628800
# c#get;;
- : int = 53
I hope you can easily see how to adapt myCounter to include fib ...