Appending lists in lambda - list

This works in F# Interactive:
let (list:(int * int) List) = []
list # [(40, 60)];;
This doesent work in my program:
let rMouseEvent =
form.MouseClick.Add(fun args -> list # [(args.X, args.Y)]))
Can someone explain why, and help me solve this?
The error says:
This expression was expected to have type
unit
but here has type
'a list -> 'a list

Your handler should not return a value, at present it returns an int * int list. You could ignore it using ignore:
let rMouseEvent = form.MouseClick.Add(fun args -> list # [(args.X, args.Y)] |> ignore)
although this is not very useful. If you want to add an item to list, you could change it to a ResizeArray:
let r = new ResizeArray<int * int>()
let rMouseEvent = form.MouseClick.Add(fun args -> r.Add((args.X, args.Y)))
alternatively you can use a ref:
let (r: (int*int) list ref) = ref []
let rMouseEvent = form.MouseClick.Add(fun args -> r := !r # [(args.X, args.Y)])

The compile error you get indicates that the event handler was expected to return unit - i.e. no value at all - but you're trying to return a (int * int) list. The expected return type indicates that the caller isn't going to look after the value you return for you, so you need to store any values you change yourself.
If you want to stick with using lists, then make your original list into ref:
let list : (int * int) List ref = ref []
and then do something like:
let rMouseEvent =
form.MouseClick.Add(fun args -> list := !list # [(args.X, args.Y)]))

Related

How can I make the find function in ocaml?

I have to implement the find function of the module List:
val find : ('a -> bool) -> 'a list -> 'a
This is that I've got, but I don't get the type of the function, so I'm really lost:
let rec find p l= match l with
[]-> raise(Not_found)
| h::t -> if h=p then p else find p t;;
This is the type of my function find:
val find : 'a -> 'a list -> 'a = <fun>
The problem is probably you misunderstood what find was supposed to do.
What you wrote is trying to find p in a list, while find takes p to be a predicate, i.e., a property. You want to find an element x in the list satisfying p, i.e., such that p x is true.
Say you have the following:
type account = { name : string; amount : int; }
let accounts = [{name = "Musterman"; amount = 10}; {name = "Musterfrau"; amount = -90}]
then you can find the account for "Musterman" by using:
List.find (fun a -> a.name = "Musterman") accounts
or accounts with a negative balance using
List.find (fun a -> a.amount < 0) accounts
Having the first argument of List.find be a function returning true when an list item is found makes List.find much more useful than a simple comparison to a know item.
If you have a list like:
let lst = [10; 1; 9; 2; ]
Then your find should take a function like:
find (fun x -> x = 10) lst
The above will find the node in the list which equals 10 if it exists.

ocaml 'a list list function tuples

let sample_table4 = [
[["11"];["21"];["31"];["41"]];
[["12"];["22"];["32"]];
[["13"];["23"]];
[["14"]]];;
This is where I'm stuck with writing a function to get one of these numbers
let tgvc (pos, table) =
match pos with
|[] -> []
|i::[j] -> List.nth (List.nth table (j-1)) (i-1)
|i::_ -> []
;;
val tgvc : int list * 'a list list list -> 'a list = <fun>
I'm supposed to get this signature
tgvc ([3;2],sample_table4);;
val tgvc : int list * ’a list list -> ’a = <fun>
-: string list = ["32"]
What's missing in the function?
I'm sure it has to be recursive now.
Even though it computes the right answer, it's not the right method. The ->[ ] is what's getting me
let rec tgvc (pos, table) = function
|_,[] -> []
|[i;1], h::_ -> List.nth h (i-1)
|[i;j], _::t -> tgvc ([i;j-1], t)
|_ -> []
|[i;j], _::t -> tgvc ([i;j-1], t)
^^^^^^^^^^^^^^^^^
Error: This expression has type int list * 'a list list list -> 'a list
but an expression was expected of type 'a list
What's missing in the function?
A lot of things. Your function simply returns one of many lists of initial input. You don't even use i indice.
I suggest you to think what your function need to do for the given input:
[i; 1], h::_ - you are "in front" of the desirable list
[i; j], _::t - not desirable list yet (some recursion maybe?)
_, [] - empty table
_ - everything else
Edit
You have two problems with your last implementation. First of all in your first and last branches you return [], I guess you would like to exit with an error, so you can throw an exception (via failwith for example). The second problem is actually in the first line: get_table_values_cell (pos, table) = function, it means that you define get_table_values_cell as function with two arguments, you give one explicitly ((pos, table)) and the second is introduced by function keyword. So all you need is to pick only one: get_table_values_cell = function

String list to Int List parsing

I have a String lists which looks like this
String list = ["150";"350";"100"]
I am now trying to parse this into a int list so i can take the values and make calculations with them. The problem i have right now is im quite new to f# and not sure how to do this.
I was thinking of making a fold function which run a System.Int32.Parse on every value in a list
let listParser list = List.fold (fun listParser a -> (System.Int32.Parse a) :: intlist) list
This function gives me String list -> Int list, but when i run this function i get
stdin(105,12): error FS0001: This expression was expected to have type
int list
but here has type
string -> string list
any better way of doing this? appreciating any form of help!
List.fold doesn't seem like the correct match for your requirement since it's a method that applies a function to each list element and accumulates the result as a single value, such as an average.
You could use List.map though;
> let list = ["150";"350";"100"];;
> let listParser list = List.map System.Int32.Parse list;;
val listParser : list:string list -> int list
> listParser list;;
val it : int list = [150; 350; 100]
What you're looking for, is the List.map function:
let list = ["150";"350";"100"]
let listOfInts = List.map System.Int32.Parse list
Using a lambda, the second line would be
let listOfInts = List.map (fun a -> System.Int32.Parse a) list
but you don't need the lambda in this case.
It's a common practice to use the pipe forward operator when working with collections in F#, like so:
let listOfInts = list |> List.map System.Int32.Parse

How to add an element to a list without returning a list?

What's the best way to insert an element in a list without returning a list? When I try to use the operator ::, it returns a list:
element :: lst
However, I would like the return value to be unit, similar to the way Hashtbl.add works.
What you want to do can't be done because lists are not changeable.
They are not changeable because this is "exactly not" how you do things in functional programming. You give the original list to a function and get a new list. If the list is good for something you keep working on it.
But there is hope: you could use a reference. Code from an interactive session:
# let mylist = ["one";"two";"tree"] ;;
val mylist : string list = ["one"; "two"; "tree"]
# mylist.[1];;
Error: This expression has type string list
but an expression was expected of type string
# mylist.(1);;
Error: This expression has type string list
but an expression was expected of type 'a array
# List.iter (function e -> print_endline e) mylist;;
one
two
tree
- : unit = ()
# let r = ref [];;
val r : '_a list ref = {contents = []}
# r := "zero" :: mylist;;
- : unit = ()
# List.iter (function e -> print_endline e) !r;;
zero
one
two
tree
- : unit = ()
# List.iter (function e -> print_endline e) ("minus" :: !r);;
minus
zero
one
two
tree
- : unit = ()
# List.iteri (fun cnt -> fun e -> Printf.printf "Element %d: %s" cnt e) !r;;
Element 0: zeroElement 1: oneElement 2: twoElement 3: tree- : unit = ()
#
Code walk:
define mylist
try to access one element in the list, not possible
another try to access one element, no go. You must be able to access it to store a new value
example of list iteration to print a list
create reference r of type '_a list ref
store string and mylist in r
iterate list in r for printing, to see if the data is there
iterate list with on the fly change of the list
finally give a (poor) example of List.iteri, in Caml syntax
I am so explicit because I was missing exactly these examples when trying to get aquainted with FP.
/Str.

Returning first value of list of tuples

I'm learning to deal with Lists and Tuples in F# and a problem came up. I have two lists: one of names and one with names,ages.
let namesToFind = [ "john", "andrea" ]
let namesAndAges = [ ("john", 10); ("andrea", 15) ]
I'm trying to create a function that will return the first age found in namesAndAges given namesToFind. Just the first.
So far I have the following code which returns the entire tuple ("john", 10).
let findInList source target =
let itemFound = seq { for n in source do
yield target |> List.filter (fun (x,y) -> x = n) }
|> Seq.head
itemFound
I tried using fst() in the returning statement but it does not compile and gives me "This expression was expected to have type 'a * 'b but here has type ('c * 'd) list"
Thanks for any help!
There are lots of functions in the Collections.List module that can be used. Since there are no break or a real return statement in F#, it is often better to use some search function, or write a recursive loop-function. Here is an example:
let namesToFind = [ "john"; "andrea" ]
let namesAndAges = [ "john", 10; "andrea", 15 ]
let findInList source target =
List.pick (fun x -> List.tryFind (fun (y,_) -> x = y) target) source
findInList namesToFind namesAndAges
The findInList function is composed of two functions from the Collections.List module.
First we have the List.tryFind predicate list function, which returns the first item for which the given predicate function returns true.
The result is in the form of an option type, which can take two values: None and Some(x). It is used for functions that sometimes give no useful result.
The signature is: tryFind : ('T -> bool) -> 'T list -> 'T option, where 'T is the item type, and ('T -> bool) is the predicate function type.
In this case it will search trough the target list, looking for tuples where the first element (y) equals the variable x from the outer function.
Then we have the List.pick mapper list function, which applies the mapper-function to each one, until the first result that is not None, which is returned.
This function will not return an option value, but will instead throw an exception if no item is found. There is also an option-variant of this function named List.tryPick.
The signature is: pick : ('T -> 'U option) -> 'T list -> 'U, where 'T is the item type, 'U is the result type, and ('T -> 'U option) is the mapping function type.
In this case it will go through the source-list, looking for matches in the target array (via List.tryFind) for each one, and will stop at the first match.
If you want to write the loops explicitly, here is how it could look:
let findInList source target =
let rec loop names =
match names with
| (name1::xs) -> // Look at the current item in the
// source list, and see if there are
// any matches in the target list.
let rec loop2 tuples =
match tuples with
| ((name2,age)::ys) -> // Look at the current tuple in
// the target list, and see if
// it matches the current item.
if name1 = name2 then
Some (name2, age) // Found a match!
else
loop2 ys // Nothing yet; Continue looking.
| [] -> None // No more items, return "nothing"
match loop2 target with // Start the loop
| Some (name, age) -> (name, age) // Found a match!
| None -> loop rest // Nothing yet; Continue looking.
| [] -> failwith "No name found" // No more items.
// Start the loop
loop source
(xs and ys are common ways of writing lists or sequences of items)
First let's look at your code and annotate all the types:
let findInList source target =
let itemFound =
seq {
for n in source do
yield target |> List.filter (fun (x,y) -> x = n) }
|> Seq.head
itemFound
The statement yield List.Filter ... means you're creating a sequence of lists: seq<list<'a * 'b>>.
The statement Seq.head takes the first element from your sequence of lists: list<'a * 'b>.
So the whole function returns a list<'a * 'b>, which is obviously not the right type for your function. I think you intended to write something like this:
let findInList source target =
let itemFound =
target // list<'a * 'b>
|> List.filter (fun (x,y) -> x = n) // list<'a * 'b>
|> Seq.head // 'a * 'b
itemFound // function returns 'a * 'b
There are lots of ways you can get the results you want. Your code is already half way there. In place of filtering by hand, I recommend using the built in val Seq.find : (a' -> bool) -> seq<'a> -> 'a method:
let findAge l name = l |> Seq.find (fun (a, b) -> a = name) |> snd
Or you can try using a different data structure like a Map<'key, 'value>:
> let namesAndAges = [ ("john", 10); ("andrea", 15) ] |> Map.ofList;;
val namesAndAges : Map<string,int> = map [("andrea", 15); ("john", 10)]
> namesAndAges.["john"];;
val it : int = 10
If you want to write it by hand, then try this with your seq expression:
let findInList source target =
seq {
for (x, y) in source do
if x = target then
yield y}
|> Seq.head
Like fst use this(below) . This way you can access all the values.
This is from F# interactive
let a = ((1,2), (3,4));
let b = snd (fst a);;
//interactive output below.
val a : (int * int) * (int * int) = ((1, 2), (3, 4))
val b : int = 2