Manipulating lists in OCaml - functional-programming

I am having issues manipulating deeply nested lists in OCaml in the below context.
class foo (pIn:int)=
object (self)
val p = pIn
val even = if (pIn mod 2) = 0 then true else (false)
method doIt = "doIt"
method isEven = even
method getP = p
end;;
let rec createListOfElements howMany = (
Random.self_init ();
if howMany > 1 then ((new foo (Random.int 10))::(createListOfElements (howMany - 1)))
else ([(new foo (Random.int 10))]) );;
let myList = createListOfElements 5;;
let rec process1 param =
if param <= 10 then
let f = new foo param in (
if f#isEven then (myList <- List.append myList (createListOfElements f#getP));
Printf.printf "%s\n" f#doIt;
process1 (param+1) )
in process1 0;;
The error I get is, "Unbound instance variable myList". How do I go about assigning the result of "List.append myList (createListOfElements f#getP) to myList in this context?
Thanks!
Edited function:
let myList = ref (createListOfElements 5);;
let rec process1 param =
if param <= 10 then
let f = new foo param in (
if f#isEven then (myList <- !myList # (createListOfElements f#getP));
Printf.printf "%s\n" f#doIt;
process1 (param+1) )
in process1 0;;

You have to use references to break persistence --since functional programming uses persistent data. Use the ref keyword in the declaration of myList:
let myList = ref (createListOfElements 5)
To dereference the list use !, so the line in question becomes
if f#isEven then
myList := !myList # f#getP;
I suggest you use an accumulator as it's in the spirit of the functional-programming style, like this:
let rec process1 lst = function
| x when x <= 10 ->
let f = new foo x in
if f#isEven then
process1 (lst # (createListOfElements f#getP)) (param+1)
else
process1 lst (param+1)
| _ -> lst
EDIT:
I didn't compile my code and didn't notice that you are using the wrong symbol to change the value of the reference. The correct symbol is, :=. See my change above. I strongly suggest you avoid references, though, and go the accumulator route.

Related

Imperative pointer type data structures in OCAML

I have a type of two-way pointer list. What I have to do is to write a procedure, that given a list, should return a list which contain only elements on the odd indexes. I'm new into OCaml, and its pointer type data structures, this is what i`ve written so far, but it doesnt work.
Error: This expression has type 'a elem option
but an expression was expected of type 'b elem
type 'a elem =
{
v : 'a;
mutable next: 'a lista;
mutable prev: 'a lista;
}
and 'a lista = 'a elem option
exception NOT_FOUND
let x = ref None;;
let value e =
match e with
| Some x -> x.v
| None -> raise NOT_FOUND;;
let generuj n x =
x := Some {v = 0; next = None; prev = None};
for i = 1 to n do
match !x with
| None -> assert false
| Some y ->
let z = ref { v = i; next = None; prev = None } in
y.next <- Some !z;
!z.prev <- Some y;
x := Some !z
done
let second l x =
let i = ref 0 in
while !l <> None do
let z = ref !x in
if (!i mod 2 = 0) then
x := {v = value !l; next = None; prev = Some !z}
else ();
let y = !l.next in
l := {v = value y; next = y.next; prev = None};
i := !i + 1
done;;
Can anybody help me to understand why it doesnt work?
From the expression value !l you can conclude that l is of type 'a elem option ref. But in the expression !l.next you aren't handling l as an option type. You need to test whether !l is None or is Some ('a elem).
Note that you do compare l against None at the beginning of the function.
Also note that the next line has the same type error. You need to set l to Some ....

F# Split Function

I'm building a merge sort function and my split method is giving me a value restriction error. I'm using 2 accumulating parameters, the 2 lists resulting from the split, that I package into a tuple in the end for the return. However I'm getting a value restriction error and I can't figure out what the problem is. Does anyone have any ideas?
let split lst =
let a = []
let b = []
let ctr = 0
let rec helper (lst,l1,l2,ctr) =
match lst with
| [] -> []
| x::xs -> if ctr%2 = 0 then helper(xs, x::l1, l2, ctr+1)
else
helper(xs, l1, x::l2, ctr+1)
helper (lst, a, b, ctr)
(a,b)
Any input is appreciated.
The code, as you have written it, doesn't really make sense. F# uses immutable values by default, therefore your function, as it's currently written, can be simplified to this:
let split lst =
let a = []
let b = []
(a,b)
This is probably not what you want. In fact, due to immutable bindings, there is no value in predeclaring a, b and ctr.
Here is a recursive function that will do the trick:
let split lst =
let rec helper lst l1 l2 ctr =
match lst with
| [] -> l1, l2 // return accumulated lists
| x::xs ->
if ctr%2 = 0 then
helper xs (x::l1) l2 (ctr+1) // prepend x to list 1 and increment
else
helper xs l1 (x::l2) (ctr+1) // prepend x to list 2 and increment
helper lst [] [] 0
Instead of using a recursive function, you could also solve this problem using List.fold, fold is a higher order function which generalises the accumulation process that we described explicitly in the recursive function above.
This approach is a bit more concise but very likely less familiar to someone new to functional programming, so I've tried to describe this process in more detail.
let split2 lst =
/// Take a running total of each list and a index*value and return a new
/// pair of lists with the supplied value prepended to the correct list
let splitFolder (l1, l2) (i, x) =
match i % 2 = 0 with
|true -> x :: l1, l2 // return list 1 with x prepended and list2
|false -> l1, x :: l2 // return list 1 and list 2 with x prepended
lst
|> List.mapi (fun i x -> i, x) // map list of values to list of index*values
|> List.fold (splitFolder) ([],[]) // fold over the list using the splitFolder function

How best to memoize based on argument only, not function closure, and inside a class?

(question edited and rewritten to reflect chat discussion results)
In one line: Given a state in a state monad, evaluate monadic function once, cache the results.
I am trying to cache the result of a function evaluation, where the key of the cache is the state of a State monad, and where I do not care about possible side effects: i.e., even if the body of the function may change in theory, I know it will be independent of the state:
f x = state { return DateTime.Now.AddMinutes(x) }
g x = state { return DateTime.Now.AddMinutes(x) }
Here, g 10 and f 10 should yield the same result, they may not differ as result to a double call to DateTime.Now, i.e., they must be deterministic. For the sake of argument, the variable state here is x.
On a same token, (g 10) - (f 5) should yield exactly 5 minutes and not a microsecond more or less.
After finding out that caching didn't work, I toned down a more elaborate solution to its bare minimum, using Don Syme's memoization pattern with maps (or dict).
The memoization pattern:
module Cache =
let cache f =
let _cache = ref Map.empty
fun x ->
match (!_cache).TryFind(x) with
| Some res -> res
| None ->
let res = f x
_cache := (!_cache).Add(x,res)
res
The caching is supposed to be used as part of a computation builder, in the Run method:
type someBuilder() =
member __.Run f =
Log.time "Calling __.Run"
let memo_me =
fun state ->
let res =
match f with
| State expr - expr state
| Value v -> state, v
Log.time ("Cache miss, adding key: %A", s)
res
XCache.cache memo_me
This doesn't work, because the cache function is different each time because of the closure, resulting in hitting a cache miss each time over. It should be independent of expr above, and dependent on state only.
I tried placing the _cache outside the cache function on module level, but then it hits the problem of generalization:
Value restriction. The value '_cache' has been inferred to have generic type
Either define '_cache' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
Which I then tried to solve using type annotations, but I ended up not being able to use it in the generic function for the same reason: it required specific type annotations then to be used:
let _cache<'T, 'U when 'T: comparison> ref : Map<'T, 'U> = ref Map.empty
Edit, a working version of the whole computation builder
Here's the computation builder as asked in the comments, tested in FSI. The caching should be dependent solely on TState, not on the whole of 'TState -> 'TState * 'TResult.
type State<'TState, 'TResult> = State of ('TState -> 'TState * 'TResult)
type ResultState<'TState, 'TResult> =
| Expression of State<'TState, 'TResult>
| Value of 'TResult
type RS<'S, 'T> = ResultState<'S, 'T>
type RS =
static member run v s =
match v with
| Value item -> s, item
| Expression (State expr) -> expr s
static member bind k v =
match v with
| Expression (State expr) ->
Expression
<| State
(fun initialState ->
let updatedState, result = expr initialState
RS.run (k result) updatedState
)
| Value item -> k item
type MyBuilder() =
member __.Bind (e, f) = RS.bind f e
member __.Return v = RS.Value v
member __.ReturnFrom e = e
member __.Run f =
printfn "Running!"
// add/remove the first following line to see it with caching
XCache.cache <|
fun s ->
match f with
| RS.Expression (State state) ->
printfn "Call me once!"
state s
| RS.Value v -> s, v
module Builders =
let builder = new MyBuilder()
// constructing prints "Running!", this is as expected
let create() = builder {
let! v = RS.Expression <| (State <| fun i -> (fst i + 12.0, snd i + 3), "my value")
return "test " + v
}
// for seeing the effect, recreating the builder twice,
// it should be cached once
let result1() = create()(30.0, 39)
let result2() = create()(30.0, 39)
Result of running the example in FSI:
Running!
Call me once!
val it : (float * int) * string = ((42.0, 42), "test my value")
Call me once!
val it : (float * int) * string = ((42.0, 42), "test my value")
Just add the Cache into the Run
member __.Run f =
printfn "Running!"
Cache.cache <|
fun s ->
match f with
| RS.Expression (State state) ->
printfn "Call me once!"
state s
| RS.Value v -> s, v
and modify the cache function to see if it really caches
module Cache =
let cache f =
let _cache = ref Map.empty
fun x ->
match (!_cache).TryFind(x) with
| Some res -> printfn "from cache"; res
| None ->
let res = f x
_cache := (!_cache).Add(x,res)
printfn "to cache"
res
and the output is
Call me once!
to cache
val it : (float * int) * string = ((42.0, 42), "test my value")
>
from cache
val it : (float * int) * string = ((42.0, 42), "test my value")

Remove duplicates from a list in SML

I just started learning functional programming in SML and I want to know how I can combine the following two functions into a single function. The function isolate deletes the duplicates of a list of any type ('a) using the helper function 'removes'.
fun isolate [] = []
| isolate (l as x::xs) = x::isolate(remove(x,xs))
fun remove (x,[]) = []
| remove (x,l as y::ys) = if x = y then remove(x,ys) else y::remove(x,ys)
So, for the purpose of better understanding the constructs in the SML, how would you include the function remove within isolate? This may seem trivial, but I have thinking about it and can't figure it out. Thank you for your help!
One method would be to just define remove inside isolate.
fun isolate [] = []
| isolate (l as x::xs) =
let fun remove (x,[]) = []
| remove (x,l as y::ys) = if x = y
then remove(x,ys)
else y::remove(x,ys)
in
x::isolate(remove(x,xs))
end
Alternately, to make deduplication one function, though all this really does is use the library function List.filter to do the same thing that remove does.
fun isolate [] = []
| isolate (x::xs) = x::isolate(List.filter (fn y => y <> x) xs)
My idea: define a nested function to check if there are duplicated elements in the list:
fun set(nums:int list)=
let fun duplicate(x:int, l:int list)=
if null l
then false
else hd l=x orelse duplicate(x,tl l)
in
if null nums
then []
else
let val s=set(tl nums)
in if duplicate(hd nums,s)
then s
else hd nums::s
end
end
But it will give a list that only remains the last one for every duplicated elements.
I want to propound the following solutions of this problem:
fun remove_duplicates(xs: int list) =
let
fun check(xs: int list, item: int) =
if null xs
then false
else if hd xs = item
then true
else check (tl xs, item)
fun go_through_list(xs: int list) =
if null xs
then []
else if check(tl xs, hd xs)
then go_through_list(tl xs)
else hd xs :: go_through_list(tl xs)
in
go_through_list(xs)
end
It's more lines of code than in the solution propounded by #qaphla
My idea is to first sort the list, then recursively return a new list without duplicates:
fun remove_duplicates(l: int list) =
if null(l)
then []
else if null(tl l)
then l
else
let
fun compare(x: int, y: int) = x > y
fun sort(l: int list) = ListMergeSort.sort(compare) l
val l_sorted = sort(l)
in
if (hd l_sorted) = (hd (tl l_sorted))
then remove_duplicates(tl l_sorted)
else (hd l_sorted)::remove_duplicates(tl l_sorted)
end

Homework help converting an iterative function to recursive

For an assignment, i have written the following code in recursion. It takes a list of a vector data type, and a vector and calculates to closeness of the two vectors. This method works fine, but i don't know how to do the recursive version.
let romulus_iter (x:vector list) (vec:vector) =
let vector_close_hash = Hashtbl.create 10 in
let prevkey = ref 10000.0 in (* Define previous key to be a large value since we intially want to set closefactor to prev key*)
if List.length x = 0 then
{a=0.;b=0.}
else
begin
Hashtbl.clear vector_close_hash;
for i = 0 to (List.length x)-1 do
let vecinquestion = {a=(List.nth x i).a;b=(List.nth x i).b} in
let closefactor = vec_close vecinquestion vec in
if (closefactor < !prevkey) then
begin
prevkey := closefactor;
Hashtbl.add vector_close_hash closefactor vecinquestion
end
done;
Hashtbl.find vector_close_hash !prevkey
end;;
The general recursive equivalent of
for i = 0 to (List.length x)-1 do
f (List.nth x i)
done
is this:
let rec loop = function
| x::xs -> f x; loop xs
| [] -> ()
Note that just like a for-loop, this function only returns unit, though you can define a similar recursive function that returns a meaningful value (and in fact that's what most do). You can also use List.iter, which is meant just for this situation where you're applying an impure function that doesn't return anything meaningful to each item in the list:
List.iter f x

Resources