I have a function that takes a list of Integer values and returns the same. In the body of the function I
need it to print out the output list before returning it. Currently it prints out the output below. I would like to print the items in the list out separated by commas without using any type of loop.
My output currently looks like:
Even numbers : [8; 10; 12; 14]
My desired output formatting looks like:
Even numbers : 8 10 12 14
let evens_only (x : List<Int32>) : List<Int32> =
let output_list = x |> List.filter(fun y -> (y % 2) = 0)
printfn "Even numbers : %A" output_list
output_list
Just map printf over the list (List.iter is similar to List.map in its functionality for this example).
let evens_only (x : List<Int32>) : List<Int32> =
let output_list = x |> List.filter(fun y -> (y % 2) = 0)
printf "Even numbers : "
List.iter (fun i -> printf "%i " i) output_list
printfn "" //extra newline
output_list
Output:
> evens_only [8; 10; 12; 14];;
Even numbers : 8 10 12 14
val it : List<Int32> = [8; 10; 12; 14]
So I came across with the op operator and I don't get the pupurse.
I defined two functions:
fun op pow1 (x,y) = Math.pow (x,y);
fun pow2 (x,y) = Math.pow (x,y);
They both have the same signatures:
val pow1 = fn : real * real -> real
val pow2 = fn : real * real -> real
And they both have the same function calls:
pow1 (5.0,6.0);
> val it = 15625.0 : real
pow2 (5.0,6.0);
> val it = 15625.0 : real
So what is the difference between those two functions? What is the idea behind op?
The op keyword undoes the infix status of the following (alphanumerical or symbolic) identifier. For example:
val n = op+ (1, 2) (* equivalent to: val n = 1 + 2 *)
val m = op mod (5, 6) (* equivalent to: val m = 5 mod 6 *)
fun op+ (x, y) = x - y (* equivalent to: fun x + y = x - y *)
These lines would be syntax errors otherwise.
This is useful when referring to a normally-infix function without immediately invoking it, such as when passing it to a higher-order function. For example:
List.foldr op+ 0 [1, 2, 3] (* equivalent to: 1 + (2 + (3 + 0)) *)
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.
It seems that I can't assign an abstract value to a ref and I'm not sure what to do.
open Big_int
let largest = ref zero_big_int;;
let depth = ref zero_big_int;;
let rec big i = (add_int_big_int i zero_big_int)
and collatz = fun num depth ->
print_endline (string_of_big_int num);
(if(eq_big_int (add_int_big_int (-1) num) zero_big_int)then(depth)else(
if eq_big_int (mod_big_int num (big 2)) zero_big_int then (collatz (div_big_int num (big 2)) (succ_big_int depth)) else (collatz (succ_big_int (mult_int_big_int 3 num)) (succ_big_int depth))))
and euler14 i =
print_endline (string_of_big_int i);
(if(lt_big_int i (big 1000000))then (
let ret = (collatz i unit_big_int) in
if(ret> !depth)then (largest:=i;depth:=ret; (euler14 (succ_big_int i))) else (euler14 (succ_big_int i))
) else (!largest));;
print_endline (string_of_big_int (euler14 (big 2)));;
The code seems to crash when I try largest:=i and depth:=ret which are both Big_nums. Is there any way around this?
2
2
1
3
3
10
5
16
8
4
2
1
Fatal error: exception Invalid_argument("equal: abstract value")
You cannot compare values of type Big_int.big_int with the polymorphic =, >, >=. Instead, you have to write your own comparison functions for all types that contain a Big_int.big_int, even if it is deeply embedded.
Using OCaml 3.12.1 or later, you can use the polymorphic comparison functions with values of type Z.t as implemented in the external library Zarith, a modern replacement for Big_int.
Being compatible with polymorphic operations is only one of the advantages of Zarith over Big_int. It is also more compact in memory, and faster.
The thing that's failing seems to be the polymorphic comparison ret > !depth, not the assignment to a ref. I would assume you can use Big_int.compare_big_int.
# let x = big_int_of_int 3;;
val x : Big_int.big_int = <abstr>
# let y = big_int_of_int 4;;
val y : Big_int.big_int = <abstr>
# x > y;;
Exception: Invalid_argument "equal: abstract value".
# compare_big_int x y;;
- : int = -1
#
(Polymorphic comparison is one of the touchy spots in OCaml.)
I'm using the Bitstring module in the following code:
let build_data_32 v wid =
let num = wid / 32 in
let v' = Int32.of_int(v) in
let rec aux lst vv w = match w with
0 -> lst
| _ -> (BITSTRING { vv : 32 } ) :: ( aux lst (Int32.succ vv) (w-1)) in
Bitstring.concat ( aux [] v' num ) ;;
Note that when you have BITSTRING { vv : 32 }
that vv is expected to be an Int32 value. I'd like to generalize this function to work with different widths of bitstrings; ie, I'd like to create a build_data_n function where the bitstring would be constructied with BITSTRING { vv : n } .
However, the problem here is that if n is less than 32 then the succ function used above would just be the succ for type int. If it's greater than 32 it would be Int64.succ Same issue above in the line let v' = Int32.of_int(v) in - for values less than 32 it would simply be: let v' = v in , whereas for values greater than 32 it would be: let v' = Int64.of_int(v) in
Is this a case where a functor would come in handy to generalize this function and if so, how would I set that up? (and if there's some other way to do this that doesn't require functors, that would be nice to know as well)
There are a few approaches available. One is to use a functor, similar to the following:
(* The signature a module needs to match for use below *)
module type S = sig
type t
val succ : t -> t
val of_int : int -> t
end
(* The functor *)
module Make(M : S) = struct
(* You could "open M" here if you wanted to save some typing *)
let build_data v =
M.succ (M.of_int v)
end
(* Making modules with the functor *)
module Implementation32 = Make(Int32)
module Implementation64 = Make(Int64)
let foo32 = Implementation32.build_data 12
let foo64 = Implementation64.build_data 12
Another is to wrap your data type in a record:
(* A record to hold the relevant functions *)
type 'a wrapper_t = { x : 'a; succ : 'a -> 'a }
(* Use values of type 'a wrapper_t in *)
let build_data v =
v.succ v.x
(* Helper function to create 'a wrapper_t values *)
let make_int32_wrapper x = { x = Int32.of_int x; succ = Int32.succ }
let make_int64_wrapper x = { x = Int64.of_int x; succ = Int64.succ }
(* Do something with a wrapped int32 *)
let foo32 = build_data (make_int32_wrapper 12)
let foo64 = build_data (make_int64_wrapper 12)
And finally, if you are using OCaml 3.12.0 or later, you can use first class modules:
(* You can use the module type S from the first example here *)
let build_data (type s) m x =
let module M = (val m : S with type t = s) in
M.succ x
let int32_s = (module Int32 : S with type t = Int32.t)
let int64_s = (module Int64 : S with type t = Int64.t)
let foo32 = build_data int32_s 12l
let foo64 = build_data int64_s 12L
Each of these approaches can be mixed and matched. You may also be able to wrap your values in variant types or objects to get a similar result.
With BITSTRING { vv : n }, i.e. using runtime-specified field length, the type of vv cannot depend on n as it is not the compile-time constant anymore, so vv is forced to int64.