Handle recursive function within an other function ocaml - functional-programming

If I have one or more recursive functions inside an Ocaml function how can I call them without exit from the main function taking their value as return of the main function?
I'm new in Ocaml so I'll try to explain me better...
If I have :
let function =
let rec recursive1 = ...
...
let rec recursive2 = ...
...
How can I call them inside function to tell it "Hey, do you see this recursive function? Now call it and takes its value."
Because my problem is that Ocaml as return of my functions sees Unit instead of the right return.
I will post the code below :
let change k v list_ =
let rec support k v list_ =
match list_ with
| [] -> []
| (i,value) :: tl -> if i = k
then (k,v) :: tl
else (i,value) :: support k v tl in
let inserted = support k v list_ in inserted
let () =
let k = [ (1,"ciao");(2,"Hola");(3,"Salut") ] in
change 2 "Aufwidersen" k
Change takes as input a key, a value and a (int * string )list and should return the same list of the input but changing the value linked to the key selected ( if in list ).
support, instead, makes the dirty job. It builds a new list and when k is found i = k it changes value and attach the tile, closing the function.
The return of change is unit when it should be (int * string) list. I think because inserted isn't taken as return of the function.

change does not return unit. The error in fact tells you exactly the opposite, that it returns (int * string) list but that it expects unit. And it expects unit because you're assigning it to a () pattern.
I don't know what you actually intend to do with the return value, as right now you don't seem to care about it, but you can fix the error by just assigning it to a name:
let result: (int * string) list =
let k = [ (1,"ciao");(2,"Hola");(3,"Salut") ] in
change 2 "Aufwidersen" k
Since it's not used I've added a type annotation to make sure we're getting what we expect here, as otherwise result could be anything and the compiler wouldn't complain. You don't typically need this if you're going to use result however, as you'd then get an error if the type doesn't unify with its usage.

Related

F# define search function

I am new to F# and am having trouble with my code. Its a simple problem to define a function, search, with that take a boolean function and a list and return an index. So for example:
> search (fun x -> x > 10) [ 2; 12; 3; 23; 62; 8; 2 ];;
val it : int = 1
> search (fun s -> s < "horse") [ "pig"; "lion"; "horse"; "cow"; "turkey" ];;
val it : int = 3
What I have as of right now finds the right match but what I cant figure out is how to return a number instead of the rest of the list. I know I'm getting the list instead of a value back because I wrote "if f head then list". What I don't know is what I should put there instead or if what I have is not going to get the result I want.
Below is the code I have written.
let rec search f list =
match list with
| [] -> [-1]
| head::tail ->
if f head then list
else search f tail
Returning a number is easy, you just... return it. Your problem is that you don't have a number to return, because you can't derive it directly from the current state. You have to keep track of the number yourself, using some internal state variable.
When using recursion you change state by calling your function recursively with "modified" arguments. You're already doing that with the list here. To keep internal state in a recursive function you have to introduce another argument, but not expose it outside. You can solve that by using an internal recursive helper function. Here's one that keeps track of the previous item and returns that when it encounters a match:
let search f list =
let rec loop list prev =
match list with
| [] -> None
| head::tail ->
if f head then prev
else loop tail (Some head)
in
loop list None
That's a silly example, but I don't want to just solve your homework for you, because then you wouldn't learn anything. Using this you should be able to figure out how to keep a counter of which position the current item is in, and return that when it matches. Good luck!
You typically define an inner recursive function to help you carry state as you loop, and then call the inner function with an initial state.
let search predicate list =
let rec loop list index =
match list with
| [] -> -1
| head::tail ->
if predicate head then index
else loop tail (index + 1)
loop list 0

Standard ML : Check conditions when iterating a list

i'm studying the programming language Standard ML and i am wondering how i can iterate a list with a check condition.
In other languages we have for loops like :
var input;
for(var i = 0; i < arr.length; i++) {
if(arr[i] == input) {
//you have arrived at your condition...
} else {
//other case
}
}
f.ex
i want to iterate through a list and check if the input variable matches a existing element in the list.
i = 5
xs = [1,5,2,3,6] --> the element matches after one iteration.
fun check i nil = []
| check i (x::xs) = if i=x
then //dowork
else //iterate;
I've gone through many documentations on how to implement this without success.
It would be really helpful if someone could give me some explaining regarding how i can use let val A in B end; inside or outside of if conditions for this kind of work.
how i can iterate a list with a check condition
fun check i nil = []
| check i (x::xs) = if i=x
then //dowork
else //iterate;
i want to iterate through a list and check if the input variable matches a existing element in the list.
I would call this a predicate combinator. It already exists in the standard library and is called List.exists. But you can also make it yourself:
fun exists p [] = false
| exists p (x::xs) = p x orelse exists p xs
This is a simplification of the if-then-else you're attempting, which would look like:
fun exists p [] = false
| exists p (x::xs) = if p x then true else exists p xs
If-then-else isn't really necessary when the result type is a boolean, since orelse, andalso and not are short-circuiting (will not evaluate their second operand if the result can be determined with the first).
Using this List.exists function to check if a list contains a specific element, you have to construct a p that compares the list element with some given value, e.g.:
fun check y xs = List.exists (fn x => ...) xs
This may seem a bit more complicated than simply writing check recursively from scratch,
fun check y [] = false
| check y (x::xs) = ... orelse check y xs
but a solution using higher-order functions is preferred for several reasons.
One is that a seasoned reader will quickly detect what you're doing when seeing List.exists: Ah, you're scanning a list for an element given a predicate. Whereas if your function is explicitly recursive, the reader will have to read the entire recursion scheme: OK, the function doesn't do anything funky, which I'd have known if I'd seen e.g. List.exists.

How to use memoize over sequence

let memoize (sequence: seq<'a>) =
let cache = Dictionary()
seq {for i in sequence ->
match cache.TryGetValue i with
| true, v -> printf "cached"
| false,_ -> cache.Add(i ,i)
}
I will call my memoize function inside this function :
let isCached (input:seq<'a>) : seq<'a> = memoize input
If the given sequence item is cached it should print cached otherwise it will continue to add sequence value to cache.
Right now I have problems with types.
When I try to call my function like this :
let seq1 = seq { 1 .. 10 }
isCached seq1
It throws an error
"The type int does not match the type unit"
I want my function to work generic even though I return printfn. Is it possible to achieve that? And while adding value to the cache is it appropriate to give the same value to tuple?
eg:
| false,_ -> cache.Add(i ,i)
I think the problem is that your memoize function does not actually return the item from the source sequence as a next element of the returned sequence. Your version only adds items to the cache, but then it returns unit. You can fix that by writing:
let memoize (sequence: seq<'a>) =
let cache = Dictionary()
seq {for i in sequence do
match cache.TryGetValue i with
| true, v -> printf "cached"
| false,_ -> cache.Add(i ,i)
yield i }
I used explicit yield rather than -> because I think that makes the code more readable. With this change, the code runs as expected for me.
Tomas P beat me to the punch, but I'll post this up anyway just in case it helps.
I'm not too sure what you are trying to achieve here, but I'll say a few things that I think might help.
Firstly, the type error. Your isCached function is defined as taking a seq of type 'a, and returning a seq of type 'a. As written in your question, right now it takes a seq of type 'a, and returns a sequence of type unit. If you try modifying the output specification to seq<'b> (or actually just omitting it altogether and letting type inference do it), you should overcome the type error. This probably still won't do what you want, since you aren't actually returning the cache from that function (you can just add cache as the final line to return it). Thus, try something like:
let memoize (sequence: seq<'a>) =
let cache = Dictionary()
for i in sequence do
match cache.TryGetValue i with
| true, v -> printf "cached"
| false,_ -> cache.Add(i ,i)
cache
let isCached (input:seq<'a>) : seq<'b> = memoize input
All this being said, if you are expecting to iterate over the same sequence a lot, it might be best just to use the library function Seq.cache.
Finally, with regards to using the value as the key in the dictionary... There's nothing stopping you from doing that, but it's really fairly pointless. If you already have a value, then you shouldn't need to look it up in the dictionary. If you are just trying to memoize the sequence, then use the index of the given element as the key. Or use the specific input as the key and the output from that input as the value.

Function with an arbitrary number of arguments in F#

I want to write a function that will take an arbitrary number of (curried) arguments and simply print them out (or perform some other unspecified action with them). Here is what I have come up with:
let print arg =
let rec print args arg =
if not (FSharpType.IsFunction(typeof<'t>)) then
printfn "%A" args
Unchecked.defaultof<'t>
else
print (box arg::args)
print []
When I try to compile this I get the error The resulting type would be infinite when unifying ''t' and ''a -> 't.
I know I could just pass the arguments as a list, but I am trying to develop an API of sorts where this would be a useful idiom to have.
Is there some clever compiler trick to make such a function possible in F# or is it a lost cause?
It seems that the two branches of the inner print want to return different types: the "then" part wants to return 't, but the "else" part wants to return 'a -> 't, where 't is necessarily the same in both branches. That is, your function tries to return either its own return type or a function from another type to its own return type. Such combined return type would, indeed, be infinite, which is in perfect accordance with what you set out to do - namely, create a function with infinite number of arguments. Though I do not know how to formally prove it, I would say this is indeed impossible.
If your goal is to simply create a list of boxed values, you could get away with defining a few infix operators.
let (<+>) a b = a # [(box b)]
let (<&>) a b = [(box a); (box b)]
let xs = 5 <&> "abc" <+> 3.0 <+> None <+> true
>> val xs : obj list = [5; "abc"; 3.0; null; true]
Alternatively, with carefully chosen operator precedence, you can apply a function (but then you'll need a terminator):
let (^>) a b = (box a)::b
let (<&>) f xs = f xs
let print xs = sprintf "%A" xs
let xs = print <&> 5 ^> "abc" ^> 3.0 ^> None ^> true ^> []
>> val xs : string = "[5; "abc"; 3.0; null; true]"

How to implement a dictionary as a function in OCaml?

I am learning Jason Hickey's Introduction to Objective Caml.
Here is an exercise I don't have any clue
First of all, what does it mean to implement a dictionary as a function? How can I image that?
Do we need any array or something like that? Apparently, we can't have array in this exercise, because array hasn't been introduced yet in Chapter 3. But How do I do it without some storage?
So I don't know how to do it, I wish some hints and guides.
I think the point of this exercise is to get you to use closures. For example, consider the following pair of OCaml functions in a file fun-dict.ml:
let empty (_ : string) : int = 0
let add d k v = fun k' -> if k = k' then v else d k'
Then at the OCaml prompt you can do:
# #use "fun-dict.ml";;
val empty : string -> int =
val add : ('a -> 'b) -> 'a -> 'b -> 'a -> 'b =
# let d = add empty "foo" 10;;
val d : string -> int =
# d "bar";; (* Since our dictionary is a function we simply call with a
string to look up a value *)
- : int = 0 (* We never added "bar" so we get 0 *)
# d "foo";;
- : int = 10 (* We added "foo" -> 10 *)
In this example the dictionary is a function on a string key to an int value. The empty function is a dictionary that maps all keys to 0. The add function creates a closure which takes one argument, a key. Remember that our definition of a dictionary here is function from key to values so this closure is a dictionary. It checks to see if k' (the closure parameter) is = k where k is the key just added. If it is it returns the new value, otherwise it calls the old dictionary.
You effectively have a list of closures which are chained not by cons cells by by closing over the next dictionary(function) in the chain).
Extra exercise, how would you remove a key from this dictionary?
Edit: What is a closure?
A closure is a function which references variables (names) from the scope it was created in. So what does that mean?
Consider our add function. It returns a function
fun k' -> if k = k' then v else d k
If you only look at that function there are three names that aren't defined, d, k, and v. To figure out what they are we have to look in the enclosing scope, i.e. the scope of add. Where we find
let add d k v = ...
So even after add has returned a new function that function still references the arguments to add. So a closure is a function which must be closed over by some outer scope in order to be meaningful.
In OCaml you can use an actual function to represent a dictionary. Non-FP languages usually don't support functions as first-class objects, so if you're used to them you might have trouble thinking that way at first.
A dictionary is a map, which is a function. Imagine you have a function d that takes a string and gives back a number. It gives back different numbers for different strings but always the same number for the same string. This is a dictionary. The string is the thing you're looking up, and the number you get back is the associated entry in the dictionary.
You don't need an array (or a list). Your add function can construct a function that does what's necessary without any (explicit) data structure. Note that the add function takes a dictionary (a function) and returns a dictionary (a new function).
To get started thinking about higher-order functions, here's an example. The function bump takes a function (f: int -> int) and an int (k: int). It returns a new function that returns a value that's k bigger than what f returns for the same input.
let bump f k = fun n -> k + f n
(The point is that bump, like add, takes a function and some data and returns a new function based on these values.)
I thought it might be worth to add that functions in OCaml are not just pieces of code (unlike in C, C++, Java etc.). In those non-functional languages, functions don't have any state associated with them, it would be kind of rediculous to talk about such a thing. But this is not the case with functions in functional languages, you should start to think of them as a kind of objects; a weird kind of objects, yes.
So how can we "make" these objects? Let's take Jeffrey's example:
let bump f k =
fun n ->
k + f n
Now what does bump actually do? It might help you to think of bump as a constructor that you may already be familiar with. What does it construct? it constructs a function object (very losely speaking here). So what state does that resulting object has? it has two instance variables (sort of) which are f and k. These two instance variables are bound to the resulting function-object when you invoke bump f k. You can see that the returned function-object:
fun n ->
k + f n
Utilizes these instance variables f and k in it's body. Once this function-object is returned, you can only invoke it, there's no other way for you to access f or k (so this is encapsulation).
It's very uncommon to use the term function-object, they are called just functions, but you have to keep in mind that they can "enclose" state as well. These function-objects (also called closures) are not far separated from the "real" objects in object-oriented programming languages, a very interesting discussion can be found here.
I'm also struggling with this problem. Here's my solution and it works for the cases listed in the textbook...
An empty dictionary simply returns 0:
let empty (k:string) = 0
Find calls the dictionary's function on the key. This function is trivial:
let find (d: string -> int) k = d k
Add extends the function of the dictionary to have another conditional branching. We return a new dictionary that takes a key k' and matches it against k (the key we need to add). If it matches, we return v (the corresponding value). If it doesn't match we return the old (smaller) dictionary:
let add (d: string -> int) k v =
fun k' ->
if k' = k then
v
else
d k'
You could alter add to have a remove function. Also, I added a condition to make sure we don't remove a non-exisiting key. This is just for practice. This implementation of a dictionary is bad anyways:
let remove (d: string -> int) k =
if find d k = 0 then
d
else
fun k' ->
if k' = k then
0
else
d k'
I'm not good with the terminology as I'm still learning functional programming. So, feel free to correct me.

Resources