Second to last item in a list in F# - f#

This is what my initial thought was and there were no issues until it was called; What is wrong with this exactly?
let SecLastItem myList=
List.rev myList
|>printfn myList.[1]
How do I rectify the problem here? What is the best way to find the 2nd to last item of a list?

printfn expects a format first printfn "%A" arg
But there is more, functional programming favors immutability so List.rev returns a new list without modifying mylist
So printing the second item in myList won't give the second to last just the second from start (if it exists otherwise it'll crash)
That said you should separate function doing something and logging/printing that' better for reuse and composability.
// trySecLastItem : 'a list -> 'a option
let trySecLastItem = List.rev >> List.tryItem 2
// usage
printfn "%d" (trySecLastItem someList) // ex Some 42 or None
Now as trySecLastItem returns an option you have to take care of that (using defaultArg for example)
// maybeSecLast : int option
let maybeSecLast = trySecLastItem someList
printfn "%d" (defaultArg maybeSecLast 42)

What is the best way to find the 2nd to last item of a list?
If you do not want to reverse the list, you can use pattern matching and return an option if the list is not long enough for a 'second to last item'. Something like this.
let rec secondToLast ls =
match ls with
| [] -> None
| h :: ht :: [] -> Some(h)
| h :: t -> secondToLast t
test with
printfn "%A" (secondToLast [1; 2; 3; 4])

You need to have a formatter with printfn
let SecLastItem myList=
let revList = List.rev myList
printfn "%A" revList.[1]

Related

F#: How to process a list of tuples?

I'm working on a homework assignment. And I'm trying to learn F# so I don't want any shortcuts besides using basic things like List.Map or lambdas or something.
I'm trying to process a list of tuples, but I'm having trouble accessing the tuples in the list.
I want to take the list of tuples, add up the numbers in each tuple, and return that number, printing it out each time.
let listTup = [(2,3,4); (4,5,6); (6,7,8)]
let getSum (a,b,c) =
a+b+c
let rec printSum tpList =
let total = 0
match tpList with
| [] -> total //return 0 if empty list
| hd::tl ->
print (getSum hd)
The first thing you want to do is map your tuples through the getSum function. This can be done very simply by piping the list of tuples into List.map getSum. Then you want to print each element in the list, so you pipe the result of List.map getSum into List.iter with the function printfn "%d". This works because of the functions having curried parameters. printfn "%d" applies the "%d" parameter to printfn and returns a function taking an integer, which it then prints. The whole thing would look like this:
let listTup = [(2,3,4); (4,5,6); (6,7,8)]
let getSum (a,b,c) =
a + b + c
let printSum tpList =
tpList |> List.map getSum |> List.iter (printfn "%d")
This prints:
9
15
21
We can even simplify the function further if we take advantage of function composition (the >> operator). Notice that printSum takes tpList as its parameter, and then just uses it as input to two functions that are pipelined together. Since pipelining just takes the output of one function and passes it as the last parameter of another function, all we really need to do is compose the function List.map getSum, which takes a list of int 3-tuples and returns a list of ints with List.iter (printfn "%d"), which takes a list of ints and returns unit. That would look like this:
let printSum = List.map getSum >> List.iter (printfn "%d")
This will print the same results, but is a simpler way of expressing the function.
F# has imperative loops as well. In this case I think an imperative loop matches the problem most idiomatically.
let listTup = [(2,3,4); (4,5,6); (6,7,8)]
for a,b,c in listTup do
let sum = a + b + c
printfn "%d" sum

Looking for something like `let` in `match` expression

Sometimes I use something like this:
match foo a with
| 1 -> printfn "%s" (foo a)
| 0 -> printfn "ok"
In this case I call foo function twice and if it is expensive call I use this code:
let tmp = foo a
match tmp with
| 1 -> printfn "%s" tmp
| 0 -> printfn "ok"
But in this case I have created variable with outer scope (regarding match expression).
I am looking for something like this:
match (foo a) as tmp with
| 1 -> printfn "%s" tmp
| 0 -> printfn "ok
What do you use in this cases ? Is there any elegant solution ?
Update - real example:
let collection = getValuesFromDatabase a
match Array.length collection with
| 0 -> printfn "nothing"
| _ -> bar collection.[0]
Option 1: use a let- or do-block
let result =
let tmp = foo a
match tmp with
| 1 -> printfn "%d" tmp
| 0 -> printfn "ok"
Nesting the whole thing under a let-block keeps from polluting the namespace with tmp. The syntax is a bit heavy, but in return it allows for arbitrary complexity of the local computation.
Alternatively, if your result is a unit, you can replace let with do:
do
let tmp = foo a
match tmp with
| 1 -> printfn "%d" tmp
| 0 -> printfn "ok"
Option 2: use pattern aliasing
When pattern-matching, you can match a value with more than one pattern at once, separating the patterns with &, e.g.:
match [1;2;3] with
| (x::_)&(_::y::_) -> printfn "First element is %d, second element is %d" x y
Here, I am matching the same list with two patterns: x::_ and _::y::_. The example is a bit silly (I could have just matched with x::y::_), but it conveys the idea.
In your example, you can use this mechanism to capture the whole value by matching it with a trivial pattern:
match foo a with
| 1&x -> printfn "%d" x
| 0 -> printfn "ok"
Update: the "real" example
This is in response to your edit, where you provided a "real" example, which deals with a collection.
This "real" example is actually different from the "toy" examples that you provided before, in that you want to capture collection, but you're matching on Array.length collection - not the same thing. In general, there is no shortcut for this, except putting it in a nested do or let block as described above. But in your specific case I could rewrite the match like this:
match getValuesFromDatabase a with
| [||] -> printfn "nothing"
| xs -> bar xs.[0]
Here, instead of calling Array.length, I match the value with an empty array. This way, since I'm matching the collection itself, I can capture it in the second match case and use it to get the first element.
If you wanted to perform a more complex check than just the empty array check, you could also use a pattern guard:
match getValuesFromDatabase a with
| xs when Array.length xs = 0 -> printfn "nothing"
| xs -> bar xs.[0]
In your real example, you can just use if. You are not really pattern matching on any complex data type which is where match shines. If you're testing whether a collection is empty, you can just write something like:
let collection = getValuesFromDatabase a
if Array.length collection = 0 then printfn "nothing"
else bar collection.[0]

Equivalent of repeated takeWhile calls: does this function have a "standard" name?

I have a scenario where the standard List.groupBy function isn't what I want, but I don't know the right name for this function so it's making it hard to search for.
I have a list of items of type 'T, and a 'T -> 'k key-producing function. The items are already somewhat "grouped" together in the list, so that when you map the list through the key function, its result will tend have the same key in a row several times, e.g. [1; 1; 1; 2; 2; 1; 1; 3; 3; 3; 1; 1]. What I want is to get a list of lists, where the inner list contains all the items for which the key-producing function returned the same value -- but it should NOT group the different sequences of 1's together.
In other words, say my data was a list of strings, and the key-producing function was String.length. So the input is:
["a"; "e"; "i"; "to"; "of"; "o"; "u"; "and"; "for"; "the"; "I"; "O"]
The output I'm looking for would be:
[["a"; "e"; "i"]; ["to"; "of"]; ["o"; "u"]; ["and"; "for"; "the"]; ["I"; "O"]]
To think of it another way: this is like taking the first item of the list and storing the result of calling the key function. Then you'd use takeWhile (fun x -> keyFun x = origKeyFunResult) to generate the first segment. Then when that takeWhile stops returning values, you record when it stopped, and the value of keyFun x on the first value that didn't return the original result -- and go on from there. (Except that that would be O(N*M) where M is the number of sequences, and would devolve into O(N^2) in many cases -- whereas it should be possible to implement this function in O(N) time).
Now, I can write that function pretty easily. That's not the question. What I want to know is whether there's a standard name for this function. Because I thought it would be called groupBy, but that's something else. (List.groupBy String.length would return [(1, ["a"; "e"; "i"; "o"; "u"; "I"; "O"]); (2, ["to"; "of"]), (3, ["and"; "for"; "the"])], but what I want in this case is for the "a/e/i", "o/u", and "I/O" lists to remain separated, and I don't want the value that the key-generating returns to be in the output data).
Maybe there isn't a standard name for this function. But if there is, what is it?
I'm a little late and it seems that you have found a solution, and it seems that there doesn't exists a single function i F# that can handle the problem.
Just for the challenge I tried to find some usable solutions and came up with the following (whether they are efficient or not is up the reader to deside):
open System
module List =
/// <summary>
/// Generic List Extension:
/// Given a comparer function the list will be chunked into sub lists
/// starting when ever comparer finds a difference.
/// </summary>
let chunkByPredicate (comparer : 'T -> 'T -> bool) list =
let rec func (i : int, lst : 'T list) : 'T list list =
if i >= lst.Length then
List.empty
else
let first = lst.[i]
let chunk = lst |> List.skip(i) |> List.takeWhile (fun s -> comparer first s)
List.append [chunk] (func((i + chunk.Length), lst))
func (0, list) |> List.where (fun lst -> not (List.isEmpty lst))
// 1. Using List.fold to chunk by string length
let usingListFold (data : string list) =
printfn "1. Using List.fold: "
data
|> List.fold (fun (acc : string list list) s ->
if acc.Length > 0 then
let last = acc.[acc.Length - 1]
let lastLength = last.[0].Length
if lastLength = s.Length then
List.append (acc |> List.take (acc.Length - 1)) [(last |> List.append [s])]
else
List.append acc [[s]]
else
[[s]]) ([])
|> List.iter (printfn "%A")
printfn ""
// 2. Using List.chunkByPredicate
let usingListChunkByPredicate<'a> (predicate : 'a -> 'a -> bool, data : 'a list) =
printfn "2. Using List.chunkByPredicate: "
data
|> List.chunkByPredicate predicate
|> List.iter (printfn "%A")
printfn ""
[<EntryPoint>]
let main argv =
let data = ["a"; "e"; "i"; "to"; "of"; "o"; "u"; "and"; "for"; "the"; "I"; "O"]
usingListFold data
usingListChunkByPredicate<string>((fun first s -> first.Length = s.Length), data)
let intData = [0..50]
usingListChunkByPredicate<int>((fun first n -> first / 10 = n / 10), intData)
Console.ReadLine() |> ignore
0

Tail Recursive map f#

I want to write a tail recursive function to multiply all the values in a list by 2 in F#. I know there is a bunch of ways to do this but i want to know if this is even a viable method. This is purely for educational purposes. I realize that there is a built in function to do this for me.
let multiply m =
let rec innerfunct ax = function
| [] -> printfn "%A" m
| (car::cdr) -> (car <- car*2 innerfunct cdr);
innerfunct m;;
let mutable a = 1::3::4::[]
multiply a
I get two errors with this though i doubt they are the only problems.
This value is not mutable on my second matching condition
and
This expression is a function value, i.e. is missing arguments. Its type is 'a list -> unit. for when i call length a.
I am fairly new to F# and realize im probably not calling the function properly but i cant figure out why. This is mostly a learning experience for me so the explanation is more important than just fixing the code. The syntax is clearly off, but can i map *2 to a list just by doing the equivalent of
car = car*2 and then calling the inner function on the cdr of the list.
There are a number of issues that I can't easily explain without showing intermediate code, so I'll try to walk through a commented refactoring:
First, we'll go down the mutable path:
As F# lists are immutable and so are primitive ints, we need a way to mutate that thing inside the list:
let mutable a = [ref 1; ref 3; ref 4]
Getting rid of the superfluous ax and arranging the cases a bit, we can make use of these reference cells:
let multiply m =
let rec innerfunct = function
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
innerfunct cdr
innerfunct m
We see, that multiply only calls its inner function, so we end up with the first solution:
let rec multiply m =
match m with
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
multiply cdr
This is really only for it's own purpose. If you want mutability, use arrays and traditional for-loops.
Then, we go up the immutable path:
As we learnt in the mutable world, the first error is due to car not being mutable. It is just a primitive int out of an immutable list. Living in an immutable world means we can only create something new out of our input. What we want is to construct a new list, having car*2 as head and then the result of the recursive call to innerfunct. As usual, all branches of a function need to return some thing of the same type:
let multiply m =
let rec innerfunct = function
| [] ->
printfn "%A" m
[]
| car :: cdr ->
car*2 :: innerfunct cdr
innerfunct m
Knowing m is immutable, we can get rid of the printfn. If needed, we can put it outside of the function, anywhere we have access to the list. It will always print the same.
We finish by also making the reference to the list immutable and obtain a second (intermediate) solution:
let multiply m =
let rec innerfunct = function
| [] -> []
| car :: cdr -> car*2 :: innerfunct cdr
innerfunct m
let a = [1; 3; 4]
printfn "%A" a
let multiplied = multiply a
printfn "%A" multiplied
It might be nice to also multiply by different values (the function is called multiply after all and not double). Also, now that innerfunct is so small, we can make the names match the small scope (the smaller the scope, the shorter the names):
let multiply m xs =
let rec inner = function
| [] -> []
| x :: tail -> x*m :: inner tail
inner xs
Note that I put the factor first and the list last. This is similar to other List functions and allows to create pre-customized functions by using partial application:
let double = multiply 2
let doubled = double a
All that's left now is to make multiply tail-recursive:
let multiply m xs =
let rec inner acc = function
| [] -> acc
| x :: tail -> inner (x*m :: acc) tail
inner [] xs |> List.rev
So we end up having (for educational purposes) a hard-coded version of let multiply' m = List.map ((*) m)
F# is a 'single-pass' compiler, so you can expect any compilation error to have a cascading effect beneath the error. When you have a compilation error, focus on that single error. While you may have more errors in your code (you do), it may also be that subsequent errors are only consequences of the first error.
As the compiler says, car isn't mutable, so you can assign a value to it.
In Functional Programming, a map can easily be implemented as a recursive function:
// ('a -> 'b) -> 'a list -> 'b list
let rec map f = function
| [] -> []
| h::t -> f h :: map f t
This version, however, isn't tail-recursive, since it recursively calls map before it cons the head onto the tail.
You can normally refactor to a tail-recursive implementation by introducing an 'inner' implementation function that uses an accumulator for the result. Here's one way to do that:
// ('a -> 'b) -> 'a list -> 'b list
let map' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (acc # [f h]) t
mapImp f [] xs
Here, mapImp is the last operation to be invoked in the h::t case.
This implementation is a bit inefficient because it concatenates two lists (acc # [f h]) in each iteration. Depending on the size of the lists to map, it may be more efficient to cons the accumulator and then do a single reverse at the end:
// ('a -> 'b) -> 'a list -> 'b list
let map'' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (f h :: acc) t
mapImp f [] xs |> List.rev
In any case, however, the only reason to do all of this is for the exercise, because this function is already built-in.
In all cases, you can use map functions to multiply all elements in a list by two:
> let mdouble = List.map ((*) 2);;
val mdouble : (int list -> int list)
> mdouble [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
Normally, though, I wouldn't even care to define such function explicitly. Instead, you use it inline:
> List.map ((*) 2) [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
You can use all the above map function in the same way.
Symbols that you are creating in a match statement are not mutable, so when you are matching with (car::cdr) you cannot change their values.
Standard functional way would be to produce a new list with the computed values. For that you can write something like this:
let multiplyBy2 = List.map (fun x -> x * 2)
multiplyBy2 [1;2;3;4;5]
This is not tail recursive by itself (but List.map is).
If you really want to change values of the list, you could use an array instead. Then your function will not produce any new objects, just iterate through the array:
let multiplyArrayBy2 arr =
arr
|> Array.iteri (fun index value -> arr.[index] <- value * 2)
let someArray = [| 1; 2; 3; 4; 5 |]
multiplyArrayBy2 someArray

Return value in F# - incomplete construct

I've trying to learn F#. I'm a complete beginner, so this might be a walkover for you guys :)
I have the following function:
let removeEven l =
let n = List.length l;
let list_ = [];
let seq_ = seq { for x in 1..n do if x % 2 <> 0 then yield List.nth l (x-1)}
for x in seq_ do
let list_ = list_ # [x];
list_;
It takes a list, and return a new list containing all the numbers, which is placed at an odd index in the original list, so removeEven [x1;x2;x3] = [x1;x3]
However, I get my already favourite error-message: Incomplete construct at or before this point in expression...
If I add a print to the end of the line, instead of list_:
...
print_any list_;
the problem is fixed. But I do not want to print the list, I want to return it!
What causes this? Why can't I return my list?
To answer your question first, the compiler complains because there is a problem inside the for loop. In F#, let serves to declare values (that are immutable and cannot be changed later in the program). It isn't a statement as in C# - let can be only used as part of another expression. For example:
let n = 10
n + n
Actually means that you want the n symbol to refer to the value 10 in the expression n + n. The problem with your code is that you're using let without any expression (probably because you want to use mutable variables):
for x in seq_ do
let list_ = list_ # [x] // This isn't assignment!
list_
The problematic line is an incomplete expression - using let in this way isn't allowed, because it doesn't contain any expression (the list_ value will not be accessed from any code). You can use mutable variable to correct your code:
let mutable list_ = [] // declared as 'mutable'
let seq_ = seq { for x in 1..n do if x % 2 <> 0 then yield List.nth l (x-1)}
for x in seq_ do
list_ <- list_ # [x] // assignment using '<-'
Now, this should work, but it isn't really functional, because you're using imperative mutation. Moreover, appending elements using # is really inefficient thing to do in functional languages. So, if you want to make your code functional, you'll probably need to use different approach. Both of the other answers show a great approach, although I prefer the example by Joel, because indexing into a list (in the solution by Chaos) also isn't very functional (there is no pointer arithmetic, so it will be also slower).
Probably the most classical functional solution would be to use the List.fold function, which aggregates all elements of the list into a single result, walking from the left to the right:
[1;2;3;4;5]
|> List.fold (fun (flag, res) el ->
if flag then (not flag, el::res) else (not flag, res)) (true, [])
|> snd |> List.rev
Here, the state used during the aggregation is a Boolean flag specifying whether to include the next element (during each step, we flip the flag by returning not flag). The second element is the list aggregated so far (we add element by el::res only when the flag is set. After fold returns, we use snd to get the second element of the tuple (the aggregated list) and reverse it using List.rev, because it was collected in the reversed order (this is more efficient than appending to the end using res#[el]).
Edit: If I understand your requirements correctly, here's a version of your function done functional rather than imperative style, that removes elements with odd indexes.
let removeEven list =
list
|> Seq.mapi (fun i x -> (i, x))
|> Seq.filter (fun (i, x) -> i % 2 = 0)
|> Seq.map snd
|> List.ofSeq
> removeEven ['a'; 'b'; 'c'; 'd'];;
val it : char list = ['a'; 'c']
I think this is what you are looking for.
let removeEven list =
let maxIndex = (List.length list) - 1;
seq { for i in 0..2..maxIndex -> list.[i] }
|> Seq.toList
Tests
val removeEven : 'a list -> 'a list
> removeEven [1;2;3;4;5;6];;
val it : int list = [1; 3; 5]
> removeEven [1;2;3;4;5];;
val it : int list = [1; 3; 5]
> removeEven [1;2;3;4];;
val it : int list = [1; 3]
> removeEven [1;2;3];;
val it : int list = [1; 3]
> removeEven [1;2];;
val it : int list = [1]
> removeEven [1];;
val it : int list = [1]
You can try a pattern-matching approach. I haven't used F# in a while and I can't test things right now, but it would be something like this:
let rec curse sofar ls =
match ls with
| even :: odd :: tl -> curse (even :: sofar) tl
| even :: [] -> curse (even :: sofar) []
| [] -> List.rev sofar
curse [] [ 1; 2; 3; 4; 5 ]
This recursively picks off the even elements. I think. I would probably use Joel Mueller's approach though. I don't remember if there is an index-based filter function, but that would probably be the ideal to use, or to make if it doesn't exist in the libraries.
But in general lists aren't really meant as index-type things. That's what arrays are for. If you consider what kind of algorithm would require a list having its even elements removed, maybe it's possible that in the steps prior to this requirement, the elements can be paired up in tuples, like this:
[ (1,2); (3,4) ]
That would make it trivial to get the even-"indexed" elements out:
thelist |> List.map fst // take first element from each tuple
There's a variety of options if the input list isn't guaranteed to have an even number of elements.
Yet another alternative, which (by my reckoning) is slightly slower than Joel's, but it's shorter :)
let removeEven list =
list
|> Seq.mapi (fun i x -> (i, x))
|> Seq.choose (fun (i,x) -> if i % 2 = 0 then Some(x) else None)
|> List.ofSeq

Resources