convert a few 2-tuples to a list of lists - ocaml

this is a question about ocaml lists and tuples. I have some 2-tuples of numbers (either integers or floats) and I want to convert it to a list of lists (with 2 elements). Assuming that I have defined a num type Int of int | Float of float, the conversion should give the following:
((1,1.0),(0.4,1),(0,0)) => [[Int 1;Float 1.0];[Float 0.4; Int 1];[Int 0;Int 0]]
or more precisely
let a = (1,1.0) and b = (0.4,1) and c = (0,0) in
myconversion (a,b,c) ;;
=> [[Int 1;Float 1.0];[Float 0.4; Int 1];[Int 0;Int 0]]
the point being the values a, b, c... are defined in several places in the source files (by people who use different signatures for their tuples).
The difficulty here is that I don't know the types of the elements of the 2-tuples (int or float, that varies depending on the tuple).

Your input data can't be represented in OCaml as you describe it. OCaml is strongly typed. For example, your example input list is an invalid value in OCaml:
# [(1,1.0);(0.4,1);(0,0)];;
Error: This expression has type float but an expression was expected of type
int
So what you describe as the essence of your problem (not knowing the types) is in fact not possible. You'll have to use some other method of representing the input. For example, you could just use floats for everything. Or you could use pairs of strings.
Update
The answer for the rewritten question is the same. In OCaml it's not possible not to know the type of something statically; i.e., at the time you're writing the program (unless it can be any type at all). It's not possible (or necessary) to query the type of something at runtime. So your question doesn't have an answer (at least as far as I can see).
For OCaml, you have to think with the type system rather than against it. After a while you start to really like it (or at least that's how it worked for me). I'd start by writing down the type you want your function myconverstion to have.
Update 2
I'll repeat my advice to treat your inputs as strings. Assuming you've parsed your input up into pairs of strings, here's some code that does what you want:
let myconversion coords =
let c1 s =
if String.contains s '.' then
Float (float_of_string s)
else
Int (int_of_string s)
in
let cp (a, b) = [c1 a; c1 b] in
List.map cp coords
Here's how it works for your input (reinterpreted as strings):
# myconversion [("1", "1.0"); ("0.4", "1"); ("0", "0")];;
- : fi list list = [[Int 1; Float 1.]; [Float 0.4; Int 1]; [Int 0; Int 0]]
Update 3
Here's some (crude) code that parses a file of numbers into coordinates represented as pairs of strings. It should work as long as the tuples in the input are well formed.
let coords fname =
let ic = open_in fname in
let len = in_channel_length ic in
let buf = Buffer.create 128 in
let () = Buffer.add_channel buf ic len in
let () = close_in ic in
let s = Buffer.contents buf in
let nums = Str.(split (regexp "[^0-9.]+") s) in
let rec mkcoords sofar = function
| [] | [_] -> List.rev sofar
| a :: b :: rest -> mkcoords ((a, b) :: sofar) rest
in
mkcoords [] nums

There are two distinct problems in your setup:
you don't know the type of the tuples parameters
you want to pass them as a single n-ary tuple
For problem 2, you would have to write a function for that type specifically, whereas you could mimic a type level list type by nesting couple of tuples:
myconversion a,(b,c) ;;
The reason is that with that setup, you could write a recursive polymorphic function on the type level list:
val myconversion : type a b. (a,b) -> num list
There would still be a problem on the last element though.
So, assuming that you could pass a sequence to your conversion function, and have it process elements of that sequence one by one, you would still need to find a way of selecting the proper function of pair conversion from the tuple type: that's basically ad-hoc polymorphism, ie. you would need to be able to overload a function on its parameters' types(1). Unfortunately, OCaml doesn't support that out of the box.
One possibility would be perhaps (I have no experience doing that) to implement an extension which would extract the type information of a given expression, and generate the correct code to process it in your own code.
A flexible technique consists in having that extension generate an algebraic description of the tuples types, and use that description as an equality witness in the code which will process the tuples:
type _ w =
| U : (unit * unit) w
| IF : 'a w -> ((int * float) * 'a) w
| FI : 'a w -> ((float * int) * 'a) w
(* other constructors if necessary *)
(* data *)
let a = 1,1.0
let b = 2.0, 2
let c = 3.0, 3
let d = 4, 4.0
let l = a,(b, (c,(d,((),()))))
(* witness *)
let w = IF (FI (FI (IF U)))
(* the type parameter of w should be the same as l type *)
let rec conv : type a b. (a * b) w -> (a * b) -> num list = fun w (x, xs) ->
match w with
U -> []
| IF w' -> let i,f = x in (Int I)::(Float f)::(conv w' xs)
(* etc *)
Here, we encode the type level nil list as (unit * unit) w.
A coalgebraic approach would require to register function overloads to the conversion function polymorphic signature within the extension, and let it pick the right one from the function overload dictionary.
There's a discussion on that topic on the LtU site.

Thanks to everybody who answered. I finally found a solution, using a bit of magic:
# type num = Int of int | Float of float;;
# let to_num x = if Obj.is_int (Obj.repr x) then
Int (Obj.magic (Obj.repr x) : int)
else
Float ((Obj.magic (Obj.repr x) : float));;
# let pair_to_num (a,b) = [to_num a; to_num b];;
# let myconversion (a,b,c) = [pair_to_num a; pair_to_num b; pair_to_num c];;
and the test:
# myconversion ((1,1.0),(0.4,1),(0,0));;
- : num list list = [[Int 1; Float 1.]; [Float 0.4; Int 1]; [Int 0; Int 0]]
# myconversion ((0,0),(1,1.0),(0.4,1));;
- : num list list = [[Int 0; Int 0]; [Int 1; Float 1.]; [Float 0.4; Int 1]]
Magic, the order does not matter and the type is recorded! I can then follow didier's idea to get rid of the pair of superfluous parentheses.

Related

f# concatenate list of objects

type Googol = {
number : float
power : float
result : float
}
let generatePowers (n:float) : list<Googol> =
let rec powerInner (n:float) (p:float) (acc : list<Googol>) =
match n with
| p when p <= 1.0 -> acc
| p when p > 1.0 -> powerInner n (p-1.0) ([{ number=n; power=p; result=n**p}]#acc)
let rec numberInner (n:float) (acc : list<Googol>) =
match n with
| n when n <=1.0 -> acc
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
numberInner n []
ProjectEuler.fsx(311,50): error FS0001: This expression was expected to have type
'Googol list'
but here has type
'Googol list -> Googol list'
I am trying to solve this problem -> https://projecteuler.net/problem=56 | but for this I need to generate powers below n < 100. When I try to concatenate [{ number=n; power=p; result=n**p}]#acc
these lists I get the error above. Explain please why error says 'Googol list -> Googol list' is in the function, does I plug a function as a parameter to the function or I plug the actual list when just after concatenation. Is # a function?
This looks like homework or practice, so first I'll give some hints to move on. Finally I'll show a version that seems to work, and then tell how I would approach the problem.
The task is to find the number a ** b, for a and b less than 100, that has the highest sum of its own digits.
The first problem is that float won't give us all the digits of a ** b, so that type is useless to solve the problem. To fix that, we turn to the BigInteger type, and the BigInteger.Pow function. Then we get a 1 followed by 200 zeroes if we run the following snippet, just like it says in the problem description.
let x: bigint = BigInteger.Pow (100I, 100)
let x: string = string x
printfn "s=%s" x
To get useful results, change the Googol type so that it uses bigint, except for power that should be an int.
Why are the functions powerInner and numberInner inside the function generatePowers? This doesn't seem to have a specific purpose, so I suggest moving them out to make this clearer.
The function powerInner do a match on n, but then goes on to name the results p, which shadows the p parameter so that it is unused. Ok, the intention here is probably to match on p rather than n, so just fix that, and then the shadowing of the p parameter is perfectly fine.
The tests first on <= 1 and then on > 1 causes incomplete matches. If the first line checks that the number is less or equal to one, then it must the greater than one in the next line. So just use n -> without the when to fix that. I also suspect you want to test <= 0 instead of 1.
This
[{ number=n; power=p; result=n**p}]#acc
can be just
{ number=n; power=p; result=n**p } :: acc
and here
(powerInner n [])
I suspect you just need a starting value for the power, which would be 99
(powerInner n 99 [])
SPOILER WARNING
After a bit of tinkering, this is what I ended up with, and it seems to print out a useful list of numbers. Note that in order to not run through all 99 by 99 results with printouts, I've used low starting numbers 3 and 5 for the countdowns here, so we get some simple printout we can study for analysis.
type Googol = { number: bigint; power: int; result: bigint }
let rec powerInner (n: bigint) (p: int) (acc: Googol list) =
match p with
| p when p <= 0 -> acc
| p ->
let newNumber = { number = n; power = p; result = n ** p }
printfn "newNumber=%0A" newNumber
powerInner n (p - 1) (newNumber :: acc)
let rec numberInner (n: bigint) (acc: Googol list) =
match n with
| n when n <= 0I -> acc
| n -> numberInner (n - 1I) ((powerInner n 5 []) # acc)
let generatePowers (n: bigint) : Googol list =
numberInner n []
let powers = generatePowers 3I
I'm not sure if this solution is correct. I'd do it differently anyway.
I would simply loop through a and b in two loops, one inside the other. For each a ** b I would convert the result to a string, and then sum the digits of the string. Then I'd simply use a mutable to hold on to whichever result is the highest. The same could be achieved in a more functional way with one of those fancy List functions.
You're missing a parameter here:
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
^^^^^^^^^^^^^^^
here
powerInner is defined with three parameters, but you're only passing two.
In F# it is not technically illegal to pass fewer parameters than defined. If you do that, the result will be a function that "expects" the remaining parameters. For example:
let f : int -> int -> string
let x = f 42
// Here, x : int -> string
let y = x 5
// Here, y : string
So in your case omitting the last parameter makes the resulting type Googol list -> Googol list, which then turns out to be incompatible with the type Googol list expected by operator #. Which is what the compiler is telling you in the error message.

F#: How to pass two lists in to a formula and return my results?

So I have this function where i'm taking in two float lists and using their respective index elements to calculate this simple formula: (x-y)^2 / x for every index (0,1,2,3...)
Here is what I have so far:
let myCalc (list1: float list) (list2: float list) : float list =
List.map2 (fun x y -> (x-y)^2 / x) list1 list2
I keep getting this error: This expression was expected to have type 'float' but here has type 'string'
How come my approach listed above won't work but this example does:
let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
let sumList = List.map2 (fun x y -> x + y) list1 list2
printfn "%A" sumList
Can someone explain how I can understand the difference between the code that I've written and the example code listed above? And yes, I already tried setting the List.map2 to a variable and then printing it out but that didn't work either. I think it has something to do with the way I'm doing my calculations, I just don't know what is wrong.
Also, I want my output result to be stored in a list of the respective x and y indexes. Please help.
The reason for this error is relatively simple, you are using the wrong power operator (^). In F #, and in the family of ML languages in general, this operator is a concatenation string operator. This is why you get this error, since the compiler expects to find two parameters of the string type in rvalue and lvalue for the^operator.
You must use the ** operator:
let myCalc (list1: float list) (list2: float list) : float list =
List.map2 (fun x y -> (x - y) ** 2. / x) list1 list2
2 is a literal of typeint, we have to specify that we want to use a literal value of type float for the expression, so this gives us this:2.

tuple access: Can't find a fixed record type

I wrote a function that is supposed to receive a list of tuples. I access the components of the tuples with # and the code compiles:
fun recheck ([], n) = []
| recheck (h::t, n) =
if ((#1 h) * (#1 h)) + ((#2 h) * (#2 h)) = n then
h::recheck(t, n)
else
recheck(t, n)
But another function that basically does the same thing, namely receiving a list of tuples and accessing those, causes an error.
fun validate ([]) = true
| validate (h::t) =
if 1 = (#1 h) then
true
else
false
Can't find a fixed record type. Found near #1
What is the difference here and why does the latter cause an error?
Edit
The first function actually does not compile on its own.
But this entire snippet does:
fun drop ([], n) = []
| drop (h::t, 0) = h::t
| drop (h::t, n) =
drop(t, n-1)
fun sts_linear (y, n) =
if y < (Math.sqrt(n)+1.0) then
let
(* x^2 + y^2 = n => x = sqrt(n-y^2) *)
val x = Math.sqrt(n - (y * y));
val xr = Real.realRound(x);
in
if (abs(x - xr) < 0.000000001) then
[(Real.trunc xr, Real.trunc y)]#sts_linear (y+1.0, n)
else
(
[]#sts_linear (y+1.0, n)
)
end
else []
fun recheck ([], n) = []
| recheck (h::t, n) =
if ((#1 h) * (#1 h)) + ((#2 h) * (#2 h)) = n then
h::recheck(t, n)
else
recheck(t, n)
fun sts (n) =
(
let
val pairs = sts_linear(0.0, Real.fromInt n);
in
recheck(drop(pairs, Real.ceil( Real.fromInt (length(pairs))/2.0 ) ), n)
end
)
Your first code doesn't compile, at least with SML/NJ:
If you got it to compile then it must have been in a nonstandard extension of SML.
The problem with both of your definitions is that there is no polymorphic idea of a tuple of arbitrary arity in SML. You can write functions to work on lists of pairs. You can write functions to work on lists of triples. But -- you can't write functions to work simultaneously on lists of pairs and lists of triples (at least if your function tries to do things with these pairs/triples as tuples).
One solution is to get rid of # and use pattern-matching to extract the components:
fun validate [] = true
| validate ((x,y)::t) =
if x = 1 then
true
else
false
But, if you really want to write a function which can polymorphically apply to either lists of pairs or list of triples (or quadruples,...), the easiest thing to do is to represent the pairs, triples, etc. as lists rather than tuples. Lists which contains lists of nonspecified size are not a problem in SML.
Trying to minimize this down, as I have seen the following work in SML/NJ
and i'm not aware of it actually being a compiler extension
val p1 = {x=0, y=0};
val p2 = {x=1, y=1};
val p3 = {x=1, y=1, z=1};
There is an awkward construct from a compiler error perspective
not many languages have errors that work in this fashion,
because the function is valid, but produces a type error
unless an invocation of the function exists to resolve the
type of 'record', thus to resolve the error more code must be added.
fun getFoo(field) = fn record => field record;
Without the following actual calling of the getX
the compiler cannot determine the type of record
of which the complete type information of ALL fields
of the record must be known to the compiler, not just the #x field.
let val getX = getFoo(#x);
val x1 = getX(p1);
val x2 = getX(p2);
val x3 = getFoo(#x)(p3);
in () end;
while the following commented out snippet results in an error because the types of
p1 and p3 are different, and so different invocations of getFoo
are required
(*
let val getX = getFoo(#x);
val x1 = getX(p1);
val x3 = getX(p3);
in () end;
*)
and the following is insufficient since it never resolves the record.
let val getX = getFoo(#x) in () end;

List transform error in OCaml

I am new to OCaml and I am trying to write a function to do this:
(4,a)(1,b)(2,c)(2,a)(1,d)(4,e) --> ((4 a) b (2 c) (2 a) d (4 e))
and this is what I wrote:
let rec transform l =
match l with
| (x,y)::t -> if x = 1 then y::transform(t) else [x; y]::transform(t)
| [] -> []
I put it in the ocaml interpreter but error generated like this:
Error: This expression has type int list
but an expression was expected of type int
Could anyone give some help?
Your example transformation doesn't make it clear what the types of the values are supposed to be.
If they're supposed to be lists, the result isn't a possible list in OCaml. OCaml lists are homogeneous, i.e., all the elements of the list have the same type. This is (in essence) what the compiler is complaining about.
Update
Looking at your code, the problem is here:
if x = 1
then y :: transform (t)
else [x; y] :: transform t
Let's say the type of y is 'a. The expression after then seems to have type 'a list, because y is the head of the list. The expression after else seems to have type 'a list list, because a list containing y is the head of the list. These aren't the same type.
The main problem is to decide how to represent something as either (4 a) or b. The usual OCaml way to represent something-or-something-else is variants, so let's define one of those:
type 'a element =
| Single of 'a
| Count of int * 'a
let rec transform = function
| [] -> []
| (x,y)::t ->
if x = 1 then Single y::transform t
else Count (x, y)::transform t
Note that this won't print in quite the way you want, unless you register a printer with the toplevel.
Or better:
let compact (x, y) =
if x = 1 then Single y else Count (x, y)
let transform list = List.map compact list

Asking about return type, list and set data structure in OCaml

I have a function compute a list to boolean matrix where num_of_name: 'a list -> 'a -> int : return a position of element in a list.
1) I would like mat_of_dep_rel : 'a list -> bool array array.
My problem is that from the first List.iter it should take a list l and not an empty list []. But if I return l instead of [], it will give me a type: ('a * 'a list) list -> boolean array array. Which is not what I want.
I would like to know how can I return mat_of_dep_rel: 'a list -> bool array array?
let mat_of_dep_rel l =
let n = List.length l in
let m = Array.make_matrix n n false in
List.iter (fun (s, ss) ->
let i = num_of_name ss s in
List.iter (fun t ->
m.(i).( num_of_name ss t) <- true) ss) [];
m;;
2) I have another functions compute equivalence classes, to compute an equivalence class : check an element i if it has a path i -> j and j -> i or itself. I would like it return for me a type int list list. In this code I force the return type 'list list by put j in [j]. My question is:
Is it correct if I force like that? If not how can I return the type I want int list list.
let eq_class m i =
let mi = m.(i) in
let aux =
List.fold_right (fun j l ->
if j = i || mi.(j) && m.(j).(i) then
[j] :: l else l) in
aux [] [];;
Another function eq_classes compute a set of equivalence classes by collect all the equivalence class. I would like to use a list data structure more than using a set. But for the moment, I am not really understand about the code saying here.
Could you please explain for me? If I want to use a list data structure, how can I use it? What is a different between a list and a set data structure in OCaml? Advance/Disadvance of its?
let eq_classes m =
IntSet.fold (fun i l -> IntMap.add i (eq_class m i) l)
IntSet.empty IntMap.empty;;
3) My last question is that. After having all the equivalence classes I would like to sort them. I have another functions
let cmp m i j = if eq_class m i = eq_class m j then 0
else if m.(i).(j) then -1 else 1;;
let eq_classes_sort m l = List.sort (cmp m) l;;
for the last function I want it return for me bool array array -> int list list not bool array array -> int list -> int list
Thank you for your help.
There are quite many things wrong or obscure about your questions, but I'll try to answer as well as possible.
Question 1
You're apparently trying to transform the representation of a dependency graph from a list to a matrix. It does not make any kind of sense to have a dependency graph represented as 'a list (in fact, there is no interesting way to build a boolean matrix from an arbitrary list anyway) so you probably intended to use an (int * int) list of pairs, each pair (i,j) being a dependency i -> j.
If you instead have a ('a * 'a) list of arbitrary pairs, you can easily number the elements using your num_of_name function to turn it into the aforementioned (int * int) list.
Once you have this, you can easily construct a matrix :
let matrix_of_dependencies dependencies =
let n = List.fold_left (fun (i,j) acc -> max i (max j acc)) 0 dependencies in
let matrix = Array.make_matrix (n+1) (n+1) false in
List.iter (fun (i,j) -> matrix.(i).(j) <- true) dependencies ;
matrix
val matrix_of_dependencies : (int * int) list -> bool array array
You can also compute the parameter n outside the function and pass it in.
Question 2
An equivalence class is a set of elements that are all equivalent. A good representation for a set, in OCaml, would be a list (module List) or a set (module Set). A list-of-lists is not a valid representation for a set, so you have no reason to use one.
Your algorithm is obscure, since you're apparently performing a fold on an empty list, which will just return the initial value (an empty list). I assume that you intended to instead iterate over all entries in the matrix column.
let equivalence_class matrix element =
let column = matrix.(element) and set = ref [] in
Array.iteri begin fun element' dependency ->
if dependency then set := element' :: !set
end column ;
!set
val equivalence_class : bool array array -> int list
I only check for i -> j because, if your dependencies are indeed an equivalence relationship (reflexive, transitive, symmetrical), then i -> j implies j -> i. If your dependencies are not an equivalence relationship, then you are in fact looking for cycles in a graph representation of a relationship, which is an entirely different algorithm from what you suggested, unless you compute the transitive closure of your dependency graph first.
Sets and lists are both well-documented standard modules, and their documentation is freely available online. Ask questions on StackOverflow if you have specific issues with them.
You asked us to explain the piece of code you provide for eq_classes. The explanation is that it folds on an empty set, so it returns its initial value - an empty map. It is, as such, completely pointless. A more appropriate implementation would be:
let equivalence_classes matrix =
let classes = ref [] in
Array.iteri begin fun element _ ->
if not (List.exists (List.mem element) !classes) then
classes := equivalence_class matrix element :: !classes
end matrix ;
!classes
val equivalence_classes : bool array array -> int list list
This returns all the equivalence classes as a list-of-lists (each equivalence class being an individual list).
Question 3
The type system is pointing out that you have defined a comparison function that works on int, so you can only use it to sort an int list. If you intend to sort an int list list (a list of equivalence classes), then you need to define a comparison function for int list elements.
Assuming that (as mentioned above) your dependency graph is transitively closed, all you have to do is use your existing comparison algorithm and apply it to arbitrary representants of each class:
let compare_classes matrix c c` =
match c, c` with
| h :: _, h' :: _ -> if matrix.(h).(h') then 1 else -1
| _ -> 0
let sort_equivalence_classes matrix = List.sort (compare_classes matrix)
This code assumes that 1. each equivalence class only appears once and 1. each equivalence class contains at least one element. Both assumptions are reasonable when working with equivalence classes, and it is a simple process to eliminate duplicates and empty classes beforehand.