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
Related
I have created a working solution for concat, but I feel that I can reduce this using List.fold_lift.
Here is my current code:
let rec concat (lists : 'a list list) : 'a list =
match lists with
| [] -> []
| hd :: tl -> hd # concat tl ;;
Here is what I have tried:
let concat (lists : 'a list list) : 'a list =
List.fold_left # lists ;;
This gives me the error: This expression has type 'a list list but an expression was expected of type
'a list
I think this is because the return value of list.fold_left gives us a list, but we are feeding it a list of lists so it then returns a list of lists again. How can I get around this without matching?
I was also playing around with List.map but with no luck so far:
let concat (lists : 'a list list) : 'a list =
List.map (fun x -> List.fold_left # x) lists ;;
Consider the type signature of List.fold_left:
('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
List.fold_left takes three arguments.
A function.
An initial value.
A list to iterate over.
List.fold_left # lists
You're making two mistakes.
First off, this parses as (List.fold_left) # (lists).
You're looking for List.fold_left (#) lists. But that's still not quite right, because...
You're only passing two arguments, with lists being the initial value, while List.fold_left expects three.
I think that you're looking for something like:
let concat lists = List.fold_left (#) [] lists
Demonstrated:
utop # let concat lists = List.fold_left (#) [] lists in
concat [[1;2;3]; [4;5;6]; [7;8;9]];;
- : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9]
It is possible to write concat as fold_left while avoiding quadractic complexity by switching temporarily to different representation of list
If I have a list l, I can easily lift into an append function:
let to_append l = fun new_list -> l # new_list
I can also get back a list from an append function with
let to_list append = append []
And since for any list l, I have to_list ## to_append l = l, this means that the to_append is one-to-one: it does not lose any information.
Moreover concatenating two appends functions is exactly function composition
let append_concat f g l = f (g l)
Since we are not building yet any concrete list, append_concat has a constant cost (we are delaying the time complexity to the moment where we will call the append function).
We can use this better behavior of append_concat to write a linear concat' function that maps a list of lists to an append function:
let concat' l =
List.fold_left
(fun append l -> append_concat append (to_append l))
(to_append [] (* aka Fun.id *))
l
Note that this concat' is not yet building a list, it is building a closure which records the list of append functions to call later.
Building concat from concat' is then a matter of transforming back my append function to a list:
let concat l = to_list (concat' l)
And it is the call of to_list which will have a time complexity equal to the size of the final list.
To check that we got the right complexity, we can test that flattening the following list
let test =
List.init 1_000_000
(fun i ->
List.init 4 (fun k -> k + 4 * i)
)
(* this is [[0;1;2;3]; [4;5;6;7]; ... [...; 3_999_999]] *)
with
let flattened = concat test
is nearly instant.
I am trying to create a function that takes the head of all the lists in the list ([[]]). So far I've found out how to take all the first ints of all the lists in the list, but I can't seem to make that into a list in the same function.
let isTable (llst : list<list<'a>>) : bool =
List.forall (fun (elem : list<'a>) -> not elem.IsEmpty && elem.Length = elem.Length) llst
let a = [[1;2;3];[4;5;6]]
printfn "%A" (isTable a)
List.iter (fun x -> printfn "%A " (List.head x)) a
Can anyone help here?
You can use List.map to apply List.head that you already found to each list.
let a = [[1;2;3];[4;5;6]]
let collectHeads l = List.map List.head l
printfn "%A" (collectHeads a) // [1,4]
Unlike List.head, List.map is a higher order function and expects a function as a parameter. Expected function should take an element of the list's type and return another element. It happens that List.head does just that: it takes a list as input and return's it's head as resulting element.
Here is an input list: [[10;2;10]; [10;50;10]; [10;1;10]].
How would I filter the second element of each sub-list?
Below is my code and when I output the result I get [[10;50;10]] but what I want is [2;50;1]. Is there anyway to fix my code? I am really trying to understand F#. Thanks for the help in advance.
let sub =
let input = [[10;2;10]; [10;50;10]; [10;1;10]]
let findIndex input elem = input |> List.findIndex ((=) elem)
let q = input |> List.filter(fun elem -> findIndex input elem = 1)
printfn "%A" q
The following will get the expected result:
let second (x:List<int>) = x.[1]
let q = List.map second input
List.map is a higher order function that makes a new list by applying a function (the first argument, here the function second that returns the second element of a list) to a list (here input):
[ [10;2;10]; [10;50;10]; [10;1;10] ]
| | |
second second second <--- mapping function
| | |
V V V
[ 2 ; 50 ; 1 ]
Use List.map, not List.filter
List.filter keeps/removes items from an input list based on the function you give it, e.g. List.filter (fun x -> x % 2 = 0) myList would keep only the even numbers in myList. You can get an idea of this functionality based on its type signature, which is val filter: ('a -> bool) -> 'a list -> 'a list, meaning it takes a function (that takes an 'a and returns a boolean: ('a -> bool)), then takes a list, and returns a list of the same type.
List.map, on the other hand, transforms each element of a list into whatever you want, based on a function you give it. In your case you would use it like so:
let input = [[10;2;10]; [10;50;10]; [10;1;10]]
let result = input |> List.map (fun numbers -> numbers.[1])
printfn "%A" result
The signature of List.map is val map: ('a -> 'b) -> 'a list -> 'b list, meaning it takes a function that maps 'as to 'bs (in your case, this would map int lists to ints), takes a list of the first thing, and returns a list of the second thing.
Use List.map and List.tryIndex
Note that if any of the sub-lists are too short, the program will crash. If this is a concern, you can use a safe version of myList.[i]; namely List.tryIndex, which returns None if the item was not found. Try this out:
// Note the last sublist
let input = [[10;2;10]; [10;50;10]; [10;1;10]; [-1]]
let result : int option list = input |> List.map (fun numbers -> List.tryIndex 1 numbers)
printfn "%A" result
// This prints:
// [Some 2; Some 50; Some 1; None]
I'm writing an interactive calculator in OCaml with some simple commands. Users should be able, among other things, to define their own simple functions (mathematical functions), for instance
let f(x) = x
let g(x) = 2*f(x)
Now, the functions should be handled like in functional languages, that means they should remember their time-of-creation environment. That means, that with a function I have to keep a closure of its environment, which is functions and variables.
I keep currently defined functions in a list of tuples formed like (functions_present_at_the_time_of_creation, variables_present_at_the_time_of_creation, function_name, function_argument_names, function_formula). When I try to add a new function to the list of functions (let's assume, that it's not currently defined and I don't have to overwrite anything), I recurrently iterate to the end of the list of functions and there would like to add a new tuple.
The problem is, assuming my current functions list is of type (a*b*c*d*e) list when i try to add a tuple with itself to the end of it, it changes its type to ((a*b*c*d*e) list*f*g*h*i) list. What can I do to be able to perform such addition of a list to itself, encapsulated in a tuple?
Here's some simple SSCCE I wrote while trying to find a workaround to this issue.
let rec add_to_end list list_copy dummy = match list with
| [] -> [(list_copy, dummy)]
| h::t -> h::(add_to_end t list_copy dummy)
let add list dummy = add_to_end list list dummy
This one tries to do it with a copy of the list. The following one is written without using of a copy (both of these examples don't work, of course):
let rec add_to_end list dummy = match list with
| [] -> [(list, dummy)]
| h::t -> h::(add_to_end t dummy)
The first example doesn't work when trying to use the function add, but when doing it for instance this way (in the interpreter):
let l = [];;
let l = add_to_end l l 1;;
let l = add_to_end l l 2;;
let l = add_to_end l l 3;;
Then it works fine. I'd appreciate any help, I may think about changing the design also, any proposals are very welcome.
Edit: Here's the output of the above commands:
# let l = [];;
val l : 'a list = []
# let l = add_to_end l l 1;;
val l : ('a list * int) list = [([], 1)]
# let l = add_to_end l l 2;;
val l : (('a list * int) list * int) list = [([], 1); ([([], 1)], 2)]
# let l = add_to_end l l 3;;
val l : ((('a list * int) list * int) list * int) list =
[([], 1); ([([], 1)], 2); ([([], 1); ([([], 1)], 2)], 3)]
It's hard to tell whether you're aware that OCaml lists are immutable. You can't add a value to the end of an existing list. An existing list can never be changed. You can create a new list with a value added to the end. If you do this, I don't see why you would want to add a pair to the end consisting of the list and the new value. I suspect you're thinking about it wrong. Here's a function that takes a list and an integer and adds the integer to the end of the list.
# let rec addi i list =
match list with
| [] -> [i]
| h :: t -> h :: addi i t
;;
val addi : 'a -> 'a list -> 'a list = <fun>
# let x = [1;2;3];;
val x : int list = [1; 2; 3]
# addi 4 x;;
- : int list = [1; 2; 3; 4]
# x;;
- : int list = [1; 2; 3]
#
The function returns a new list with the value added to the end. The original list isn't changed.
As a side comment, it's much more idiomatic to add values to the front of a list. Repeatedly adding to the end of the list is slow--it gives quadratic behavior. If you want the other order, the usual thing to do is add everything to the front and then reverse the list--this is still linear.
Edit
Apparently you really want a function that looks something like this:
let f a list = list # [(list, a)]
This is not realistically possible, the types don't work out right. A list can contain things of only one type. So you can conclude that the type of the list t is the same as the type (t, v) list, where v is the type of a. This is a recursive type, not something you would really want to be working with (IMHO).
You can actually get this type in OCaml using -rectypes:
$ ocaml -rectypes
OCaml version 4.00.0
# let f a list = list # [(list, a)];;
val f : 'a -> (('b * 'a as 'c) list as 'b) -> 'c list = <fun>
#
But (as I say) it's something I would avoid.
Edit 2
Now that I look at it, your first code sample avoids requiring a recursive type because you
specify two different copies of the list. Until you call the function with the same list, these are potentially different types. So the function type is not recursive. When you call with two copies of the same list, you create a new value with a type that's different than the type of the list. It only works because you're using the same name l for different values (with different types). It won't work in a real program, where you'd need a single type representing your list.
As another side comment: the beauty of adding values to the beginning of a list is that the old value of the list is still there. It's the tail of the new list. This seems lot closer to what you might actually want to do.
is there a way to iterate list over the list through List.map?
I know List.map takes single function and list and produce a list that the function applies to all elements. But what if i have a list of function to apply a list and produce list of the list ?
Your question is not very clear, however as far as I understand it, you have a list of functions and a list of values. If you want to apply all functions to all elements then you can write this:
(* // To get one nested list (of results of all functions) for each element *)
List.map (fun element ->
List.map (fun f -> f element) functions) inputs
(* // To get one nested list (of results for all elements) for each function *)
List.map (fun f ->
List.map (fun element -> f element) inputs) functions
In case this is not what you wanted, could you try clarifying the question a little bit (perhaps some concrete example would help)?
Are you allowed to use List.map2? Because then this is simple:
let lista = [(fun x -> x + 1); (fun x -> x + 2); (fun x -> x + 3)];;
let listb = [1; 1; 1];;
let listc = List.map2 (fun a b -> (a b)) lista listb;;
The output would be [2; 3; 4]
Edit: wait, I think I read your problem wrong. You want to get a list of lists, where each list contains a list of a function applied to the initial list? In other words, for the lista and listb above, you'd get:
[[2;2;2];[3;3;3];[4;4;4]]
Is this correct?
You can try this :
let rec fmap fct_list list = match fct_list with
[] -> //you do nothing or raise sth
head::tail -> List.map head list :: fmap tail list;;