can't define a new variable to hold my rlist - ocaml

I'm learning about imperative programming in Ocaml and I have the following situation where I'm trying to reverse a linked list:
these are my two defined types:
type cell = { data : int; next : rlist; }
and rlist = cell option ref
and here is my function reverse:
let reverse (head:rlist) =
let rec helper ((head: rlist),(tmp: rlist)) =
match !head with
| None -> tmp
| Some c when !(c.next) = None ->
c.next := !tmp ; tmp := Some c ; tmp
| Some c ->
let a = ref Some !(c.next) ;
c.next := !tmp ;
tmp := Some c ;
helper (a,tmp)
in
helper (head, ref None)
this version will give me Syntax error but if I replace: let a = ref Some !(c.next) with head := !(c.next) it will work. Therefore, there is something wrong with the declaration of my let.

This expression:
ref Some !(c.next)
is parsed like this:
(ref Some) !(c.next)
essentially because function application in OCaml has very high precedence.
You should parenthesize like this:
ref (Some !(c.next))
After fixing this problem you have another syntax problem. This expression:
let a = ref (Some !(c.next));
is not valid. You need to have in after let. The short description is that inside a function let is used to introduce a local variable, and the expression that uses the local variable appears after in. The in is required. You can fix this by changing the ; at the end to in.
After fixing these two syntax problems you have at least one type error. But I hope this helps you make progress.

Related

Deleting variables in Ocaml

I have not been able to find anyone previously asking this :
How do you let go of a variable in OCaml ? Python has del and I assume OCaml has a similar function, but I cannot find it. Is it even possible to delete a variable ?
If not, then how does one manage variables in OCaml ?
I it not possible to let go of a variable in OCaml with a keyword. However you may use the variable scope in such a way :
let a = b in
print_endline a ;
...
Is different from :
( let a = b in
print_endline a ) ;
...
In the first one, you may access a inside ..., but not in the second.
You can also shadow a variable :
let a = b in
print_endline a ;
let a = () in
...
Inside ..., it will be impossible to access the original a: there is a new variable named a, the old one is "deleted" (the correct term being shadowed).
OCaml also allows you to declare variables anywhere, not matter how "small" the expression :
print_endline (let a = b in a) ;
...
is perfectly valid, and a is only defined inside the ( ). The printed value will be the same than in the first example.
The closest counterpart of a Python variable in OCaml is a reference (which is a mutable field of a record). In Python, you commonly delete a variable to let the GC do it work and collect the variable contents as soon as possible. You could do this in OCaml as well by assigning a new value to the reference. Commonly, you would use the option type or some other container to store values in references, e.g.,
let foo = ref None
let () =
foo := Some big_data_structure; (* assigning *)
foo := None (* deleting *)
or
let foo = ref []
let () =
foo := [some; huge; list];
foo := []
If we will speak about immutable variables, then you can also speed up their collection by making sure that their lifetime is as small as possible. Therefore it is a common practice to bind a result of a transformation of an immutable value to the same variable as it was before (aka shadowing, rebinding, hiding), e.g.,
let names = ["ahura"; "bahman"; "dana"; "ervin"]
let names = List.map String.capitalize names
(* previous names are no longer accessible here, so GC can collect them *)
Here we made sure that the old names are not accessible so that the GC can collect them in the nearest minor collection.

Declaring type of function in SML

I'm new to ML, but in other languages that use type inference, I have learned the habit of omitting the type of a thing whenever the inference on the right hand side is obvious to a human reader, and explicitly declaring the type of a thing whenever the inference is not obvious to a human. I like this convention, and would like to continue with it in my ML code.
I have the following example function declarations, that are equivalent:
fun hasFour [] = false
| hasFour (x::xs) = (x = 4) orelse hasFour xs
is equivalent to
val rec hasFour: int list -> bool =
fn [] => false
| (x::xs) => (x = 4) orelse hasFour xs
I like the latter form not only because it's easier for me to figure out what type the function is when I read it, but also because it explicitly declares the type of the function, and hence, if I screw something up in my implementation, there is no chance of accidentally declaring something that's syntactically valid but the wrong type, which is harder to debug later.
My question is: I want to use fun instead of val rec, because anonymous fn's can only take one parameter. So the latter technique is not syntactically valid for a function like int -> int -> bool. Is there a way to explicitly declare the type in fun? Or have I named all the preferred alternatives in this post, and should simply follow one of these patterns? The only way I could find to use fun with explicit type declaration was to add a type declaration to each parameter in the pattern, which is quite ugly and horrible, like so:
fun hasFour ([]:int list):bool = false
| hasFour (x::xs) = (x = 4) orelse hasFour xs
A colleague showed me some code following a pattern like this:
fun hasFour [] = false
| hasFour (x::xs) = (x = 4) orelse hasFour xs
val _ = op hasFour: int list -> bool
By declaring an unnamed variable and setting it to an instance of the function with a forced type, we effectively achieve the desired result, but the val _ must appear below the fully defined function, where it's less obvious to a human reader, unless you simply get used to this pattern and learn to expect it.
I asked a very similar question, Can I annotate the complete type of a fun declaration?, recently.
Your current solution would have been a nice answer to that.
You can have multiple curried arguments with multiple fn, e.g. like:
val rec member : ''a -> ''a list -> bool =
fn x => fn [] => false
| y::ys => x = y orelse member x ys
Or you can do as you currently do, or as matt suggests:
local
fun member _ [] = false
| member x (y::ys) = x = y orelse member x ys
in
val member = member : ''a -> ''a list -> bool
end
But the combination of using fun and having the complete type signature listed first is yet elusive.
For production-like code, the norm is to collect type signatures in a module signature. See ML for the Working Programmer, ch. 7: Signatures and abstraction, pp. 267-268. Although I imagine you'd want to use Ocaml then.

What is <cycle> in data?

(I use OCaml version 4.02.3)
I defined a type self
# type self = Self of self;;
type self = Self of self
and its instance s
# let rec s = Self s;;
val s : self = Self <cycle>
Since OCaml is a strict language, I expected defining s will fall into infinite recursion. But the interpreter said s has a value and it is Self <cycle>.
I also applied a function to s.
# let f (s: self) = 1;;
val f : self -> int = <fun>
# f s;;
- : int = 1
It seems s is not evaluated before the function application (like in non-strict language).
How OCaml deal with cyclic data like s? Self <cycle> is a normal form?
OCaml is indeed an eager language, however s is a perfectly valid and fully evaluated term that happens to contain a cycle. For instance, this code yields the expected result:
let f (Self Self x) = x
f s == s;;
More precisely, the memory representation of constructors with at n arguments are boxed and read like this:
⋅—————————————————————————————————————————————⋅
| header | field[0] | field[1] | ⋯ | fiekd[n] |
⋅—————————————————————————————————————————————⋅
The header contains metadata whereas field[k] is an OCaml value, i.e. either an integer or a pointer. In the case of s, Self has only one argument, and thus only one field field[0]. The value of field[0] is then simply a pointer towards the start of the block. The term s is thus perfectly representable in OCaml.
Moreover, the toplevel printer is able to detect this kind of cycles and print an <cycle> to avoid falling into an infinite recursion when printing the value of s. Here, <cycle>, like <abstr> or <fun>, represents just a kind of value that the toplevel printer cannot print.
Note, however, that cyclical value will trigger infinite recursion in many situations, for instance f s = s where (=) is the structural equality
and not the physical one (i.e. (==)) triggers such recursion, another example would be
let rec ones = 1 :: ones;; (* prints [1;<cycle>] *)
let twos = List.map ((+) 1) ones;; (* falls in an infinite recursion *)

How to create an empty list of a specific runtime type

Given a the .Net Type, say typeof<string>, at runtime how does one created the equivalent of string list = []?
My motivation is that when using FSharpValue.MakeRecord to create a record based on values parsed the values need to be passed as a obj[]. I've been up casting the arguments using box and that has worked except for with lists. The issue I've encountered is that a empty untyped list list can't be boxed and then unboxed. The specific error returned is:
System.InvalidCastException: Unable to cast object of type
'Microsoft.FSharp.Collections.FSharpList`1[System.Object]'
to type
'Microsoft.FSharp.Collections.FSharpList`1[System.String]'.
An empty typed list can be boxed and unboxed so I've tried to find a way to cast a list to a runtime type, e.g. a Type returned by typeof<> but with no luck.
type Test = {Names : string list}
// fails
let genericList = []
{Names = unbox (box genericList)}
//works
let typedList : string list = []
{Names = unbox (box typedList)}
//works
let genericNonEmptyList = ["Bill"]
{Names = unbox (box genericNonEmptyList)}
Using reflection you can get the List module and call the generic empty method:
open System
open System.Reflection
let emptyList (t:Type) =
Assembly.GetAssembly(typeof<_ list>)
.GetType("Microsoft.FSharp.Collections.ListModule")
.GetMethod("Empty", BindingFlags.Static ||| BindingFlags.Public)
.MakeGenericMethod(t)
.Invoke(null, [||])
use as follows:
let itemType = typeof<string>
let emptyStringList = emptyList(itemType) :?> string list
If you are calling that quite often, consider caching (reduces execution time by ~1/3):
let emptyList =
let empty =
Assembly.GetAssembly(typeof<_ list>)
.GetType("Microsoft.FSharp.Collections.ListModule")
.GetMethod("Empty", BindingFlags.Static ||| BindingFlags.Public)
fun (t:Type) -> empty.MakeGenericMethod(t).Invoke(null, [||])
Let me add one more alternative answer - although both of the existing methods work, they rely on understanding how F# represents lists. In the first case, you need to know there is Empty method and in the second case, you need to know there is a union case called Empty.
I generally prefer to do this by defining a helper type and using reflection over my custom type:
type ListHelper =
static member Empty<'T>() : list<'T> = []
let makeEmpty =
let empty = typeof<ListHelper>.GetMethod("Empty")
let emptyArr : obj[] = [| |]
fun ty -> empty.MakeGenericMethod([| ty |]).Invoke(null, emptyArr)
This gives you quite simple function that can cache the MethodInfo (you could even use Expression to pre-compile and cache the invocations) and does not rely on clever tricks.
#CaringDev's answer using .NET reflection is fine, but you can also use the F#-specific reflection module to create instances of union cases:
let empty ty =
let uc =
Reflection.FSharpType.GetUnionCases(typedefof<_ list>.MakeGenericType [|ty|])
|> Seq.filter (fun uc -> uc.Name = "Empty")
|> Seq.exactlyOne
Reflection.FSharpValue.MakeUnion(uc, [||])
I'm way late to the party, but I was trying to do the same thing. I found a way to do this with pattern matching:
let emptyListFromExample e =
match [e] with
| [] -> []
| x::xs -> xs
This will give you an empty list of any type, provided you can construct a value of that type to start it off.
How about using Seq.cast to cast the empty generic list?
type Test = {Names : string list}
let genericList = []
let test = {Names = unbox (box genericList ) |> Seq.cast<string> |> Seq.toList}
test.Names //val it : string list = []

OCaml: check references are all set

I'd like to write a function that is given a list of option references, and checks that each reference is not None. That is, I'd like a function
let check rs =
List.for_all (fun r -> (!r) != None) rs
let _ =
check [ref (Some 5); ref (Some true)]
This doesn't work. The compiler can't find a type for the list [ref (Some 5); ref (Some true)], even though the check function seems inherently ok, with its nice polymorphic 'a option ref list -> bool type.
Is there any way to make this work?
My real situation, from which I've distilled the toy example above, is that I'm parsing a number of command-line arguments into a bunch of references. Some of the arguments are strings and some are ints, etc. Initially all of the references are set to None, and when the parser finds a command-line argument it sets the corresponding reference to Some .... Having done the parsing, I find myself wanting to iterate over a subset of the references to make sure they're not still None, because I want the corresponding command-line arguments to be mandatory.
OCaml doesn't support heterogeneous containers. You can try to solve your problem like this:
type arg =
| Unset
| Int of int
| Bool of bool
(* etc *)
let check rs =
List.for_all (fun r -> (!r) <> Unset) rs
let _ =
check [ref (Int 5); ref (Bool true); ref Unset]
One way to look at your problem is that your list of parameters can't be given a type in OCaml:
# [ ref (Some 5); ref (Some true) ];;
Error: This expression has type bool option ref
but an expression was expected of type int option ref
Type bool is not compatible with type int
If you're willing to wrap your references inside an object interface, you can have the list:
# class cr x = object method is_set = !x <> None end;;
class cr : 'a option ref -> object method is_set : bool end
# let reflist = [ new cr (ref (Some 5)); new cr (ref (Some true))];;
val reflist : cr list = [<obj>; <obj>]
Then you can check all the elements of the list:
# List.for_all (fun x -> x#is_set) reflist;;
- : bool = true