Assume I have a function f that takes n arguments of the same type f: 'a * 'a * ... * 'a -> 'b
Assume I have a list lof n 'a elements,
Does the functor call_function_with_list exist? It would mean this:
call_function_with_list f l = f l[0] l[1] ... l[n-1]
Observe that I am not interested in specifying a particular call_function_with_list for a fixed number n (which could be done quite simply) but I am interested in having a general call_function_with_list that works for all n
You can't (without resorting to the dark magic of the Obj module, that is). Indeed, there are two issues. First OCaml's type system cannot represents something like 'a list -> ('a * 'a * ... * 'a) where ... actually depends on the length of the argument (you could do something like that in Coq for instance). Second, in OCaml an n-uple is not an iterated version of a pair, i.e. a value of type 'a * 'a * 'a is neither a value of type 'a * ('a * 'a) nor of type ('a * ('a * 'a)), so that you cannot build your nuple step by step from the elements of the list.
# let x = (1,2,3);;
val x : int * int * int = (1, 2, 3)
# let y = (1,(2,3));;
val y : int * (int * int) = (1, (2, 3))
# let z = (1,2),3;;
val z : (int * int) * int = ((1, 2), 3)
# x = y;;
Error: This expression has type int * (int * int)
but an expression was expected of type int * int * int
# x = z;;
Error: This expression has type (int * int) * int
but an expression was expected of type int * int * int
Related
for an example, if a function receives a function as a factor and iterates it twice
func x = f(f(x))
I have totally no idea of how the code should be written
You just pass the function as a value. E.g.:
let apply_twice f x = f (f x)
should do what you expect. We can try it out by testing on the command line:
utop # apply_twice ((+) 1) 100
- : int = 102
The (+) 1 term is the function that adds one to a number (you could also write it as (fun x -> 1 + x)). Also remember that a function in OCaml does not need to be evaluated with all its parameters. If you evaluate apply_twice only with the function you receive a new function that can be evaluated on a number:
utop # let add_two = apply_twice ((+) 1) ;;
val add_two : int -> int = <fun>
utop # add_two 1000;;
- : int = 1002
To provide a better understanding: In OCaml, functions are first-class
values. Just like int is a value, 'a -> 'a -> 'a is a value (I
suppose you are familiar with function signatures). So, how do you
implement a function that returns a function? Well, let's rephrase it:
As functions = values in OCaml, we could phrase your question in three
different forms:
[1] a function that returns a function
[2] a function that returns a value
[3] a value that returns a value
Note that those are all equivalent; I just changed terms.
[2] is probably the most intuitive one for you.
First, let's look at how OCaml evaluates functions (concrete example):
let sum x y = x + y
(val sum: int -> int -> int = <fun>)
f takes in two int's and returns an int (Intuitively speaking, a
functional value is a value, that can evaluate further if you provide
values). This is the reason you can do stuff like this:
let partial_sum = sum 2
(int -> int = <fun>)
let total_sum = partial_sum 3 (equivalent to: let total_sum y = 3 + y)
(int = 5)
partial_sum is a function, that takes in only one int and returns
another int. So we already provided one argument of the function,
now one is still missing, so it's still a functional value. If that is
still not clear, look into it more. (Hint: f x = x is equivalent to
f = fun x -> x) Let's come back to your question. The simplest
function, that returns a function is the function itself:
let f x = x
(val f:'a -> 'a = <fun>)
f
('a -> 'a = <fun>)
let f x = x Calling f without arguments returns f itself. Say you
wanted to concatenate two functions, so f o g, or f(g(x)):
let g x = (* do something *)
(val g: 'a -> 'b)
let f x = (* do something *)
(val f: 'a -> 'b)
let f_g f g x = f (g x)
(val f_g: ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>)
('a -> 'b): that's f, ('c -> 'a): that's g, c: that's x.
Exercise: Think about why the particular signatures have to be like that. Because let f_g f g x = f (g x) is equivalent to let f_g = fun f -> fun g -> fun x -> f (g x), and we do not provide
the argument x, we have created a function concatenation. Play around
with providing partial arguments, look at the signature, and there
will be nothing magical about functions returning functions; or:
functions returning values.
I am trying to create a list of lists meaning my result should be like
thatgraph = [[0,[1,2]],[1,[1,3],[1,4],[1,5]],[2,[3,4],[4,4],[5,5],[5,10]]
The code i use is :
fun pin2graph (pin,thatgraph,i,j,rows,cols,havepizza) =
if (i<rows) andalso (j<cols-1) then
(
pin2graph (pin,thatgraph::((i*cols+j),(getAdjacent (pin,i,j,rows,cols,havepizza))),i,j+1,rows,cols,havepizza)
)
else if (i<rows) then
(
pin2graph (pin,thatgraph::((i*cols+j),(getAdjacent (pin,i,j,rows,cols,havepizza))),i+1,0,rows,cols,havepizza)
)
else thatgraph
The getadjacent function is of type :
val getAdjacent = fn
: char Array2.array * int * int * int * int * 'a -> (int * 'a) list
the 'a is actually a real number so the real type is (int * real) list .
Whatever i have tried i always get an operand and operator mismatch with most common being :
operator domain: _ * _ list
operand: _ * (int * (int * 'Z) list)
Any hint would be greatly appreciated , running out of ideas
Apparently the 2 types below are different, but why ?
type 'a llist = Nil | Cons of 'a * (unit -> 'a llist)
vs
type 'a llist = Nil | Cons of ('a * unit -> 'a llist)
Doesn't Cons take a tuple as argument in both cases ?
It's a subtle difference, but the representation is different. It can be seen on the following example:
type ta = A of int * int
type tb = B of (int * int)
A is a constructor with two arguments, and B is a constructor with a single tuple argument.
You can see the difference by inspecting the size of the objects at runtime:
let size x =
Obj.size (Obj.repr x)
let () = Printf.printf "%d %d\n" (size (A (2, 3))) (size (B (2, 3)))
This will display "2 1" - in the second case, only a pointer to the tuple is stored, and the tuple is stored in another block.
This also means that you can manipulate the tuple itself:
let get_a (A x) = x (* error: The constructor A expects 2 argument(s),
but is applied here to 1 argument(s) *)
let get_b (B x) = x (* works *)
If i put this code to utop line by line, then it works, but if I compile it as programm, then I see error.
module List = Core.Std.List;;
let () =
let shifts = [ (-1, -1); (0, -1) ] in
let first = List.nth shifts 0 in
let (a, b) = first in
Printf.printf "%d %d\n" a b;
;;
And error message:
Error: This expression has type (int * int) option
but an expression was expected of type 'a * 'b
What wrong with types and why it works in utop?
It looks to me like Core.Std.List.nth has the type 'a list -> int -> 'a option in order to handle the case when the int is out of range. The standard library List.nth has the type 'a list -> int -> 'a. It raises an exception for an out-of-range int.
If you're using Core.Std.List in one case but the standard List in the other, this would explain the difference.
I'm encoding a form of van Laarhoven lenses in OCaml, but am having difficulty due to the value restriction.
The relevant code is as follows:
module Optic : sig
type (-'s, +'t, +'a, -'b) t
val lens : ('s -> 'a) -> ('s -> 'b -> 't) -> ('s, 't, 'a, 'b) t
val _1 : ('a * 'x, 'b * 'x, 'a, 'b) t
end = struct
type (-'s, +'t, +'a, -'b) t =
{ op : 'r . ('a -> ('b -> 'r) -> 'r) -> ('s -> ('t -> 'r) -> 'r) }
let lens get set =
let op cont this read = cont (get this) (fun b -> read (set this b))
in { op }
let _1 = let build (_, b) a = (a, b) in lens fst build
end
Here I am representing a lens as a higher order type, a transformer of CPS-transformed functions ('a -> 'b) -> ('s -> 't) (as was suggested here and discussed here). The functions lens, fst, and build all have fully generalized types but their composition lens fst build does not.
Error: Signature mismatch:
...
Values do not match:
val _1 : ('_a * '_b, '_c * '_b, '_a, '_c) t
is not included in
val _1 : ('a * 'x, 'b * 'x, 'a, 'b) t
As shown in the gist, it's perfectly possible to write _1
let _1 = { op = fun cont (a, x) read -> cont a (fun b -> read (b, x)) }
but having to manually construct these lenses each time is tedious and it would be nice to build them using higher order functions like lens.
Is there any way around the value restriction here?
The value restriction is a limitation of the OCaml type system that prevents some polymorphic values from being generalized, i.e. having a type that is universally quantified over all type variables. This is done to preserve soundness of the type system in the presence of mutable references and side effects.
In your case, the value restriction applies to the _1 value, which is defined as the result of applying the lens function to two other functions, fst and build. The lens function is polymorphic, but its result is not, because it depends on the type of the arguments it receives. Therefore, the type of _1 is not fully generalized, and it cannot be given the type signature you expect.
There are a few possible ways to work around the value restriction in this case:
Use explicit type annotations to specify the type variables you want to generalize. For example, you can write:
let _1 : type a b x. (a * x, b * x, a, b) Optic.t = lens fst (fun (_, b) a -> (a, b))
This tells the compiler that you want to generalize over the type variables a, b, and x, and that the type of _1 should be a lens that works on pairs with any types for the first and second components.
Use functors to abstract over the type variables and delay the instantiation of the lens function. For example, you can write:
module MakeLens (A : sig type t end) (B : sig type t end) (X : sig type t end) = struct
let _1 = lens fst (fun (_, b) a -> (a, b))
end
This defines a functor that takes three modules as arguments, each defining a type t, and returns a module that contains a value _1 of type (A.t * X.t, B.t * X.t, A.t, B.t) Optic.t. You can then apply this functor to different modules to get different instances of _1. For example, you can write:
module IntLens = MakeLens (struct type t = int end) (struct type t = int end) (struct type t = string end)
let _1_int = IntLens._1
This gives you a value _1_int of type (int * string, int * string, int, int) Optic.t.
Use records instead of tuples to represent the data types you want to manipulate with lenses. Records have named fields, which can be accessed and updated using the dot notation, and they are more amenable to polymorphism than tuples. For example, you can write:
type ('a, 'x) pair = { first : 'a; second : 'x }
let lens_first = lens (fun p -> p.first) (fun p b -> { p with first = b })
let lens_second = lens (fun p -> p.second) (fun p b -> { p with second = b })
This defines two lenses, lens_first and lens_second, that work on any record type that has a first and a second field, respectively. You can then use them to manipulate different kinds of records, without having to worry about the value restriction. For example, you can write:
type point = { x : int; y : int }
type person = { name : string; age : int }
let p = { x = 1; y = 2 }
let q = lens_first.op (fun x f -> x + 1) p (fun p -> p)
(* q is { x = 2; y = 2 } *)
let r = { name = "Alice"; age = 25 }
let s = lens_second.op (fun x f -> x + 1) r (fun r -> r)
(* s is { name = "Alice"; age = 26 } *)