F# Cumulative Product of an array - f#

Using F#, I would like to calculate the cumulative product of an Array without any loop. A first idea will be to use Array.fold and Array.map but I don't see how I can use them. What do you suggest? or peharps using a recursive function? Many thanks in advance for your help.

If you need the product of all elements, you can use fold indeed:
> let a = [|1;2;3;4;5|];
> a |> Array.fold (*) 1;;
val it : int = 120
If you need the intermediate (cumulative) results, you can use scan. Scan takes each element in the array and applies a function (product in this case) to the element, and the previous cumulative result. Starting with a value of 1 for the accumulator, we get:
> a |> Array.scan (*) 1;;
val it : int [] = [|1; 1; 2; 6; 24; 120|]

You can use Array.scan:
let products = arr |> Array.scan (*) 1;;

Others already gave nice answers, just a general remark. Your statement "or perhaps a recursive function" is usually unnecessary. About 95% of the time, you can use a fold instead. Where recursive functions are the way to go, is if you need a non-standard iteration order.
Apart from that think in terms of not how to do the whole operation at once, i.e. how to process a list of numbers in your case, but just think how to do it for one item.
From that you get that you e.g. need to multiply the item with the accumulator. So in this case your no longer needs to be recursive, because with fold you abstracted over the iteration itself.

If you want to use tail recursive function to do the job. You might want to try sth similar:
let l = [1;2;3;4;5]
let product lst =
let rec pTR acc = function
| [] -> acc
| h::t -> pTR (h * acc) t
pTR 1 lst
product l

Related

Compare values in a list

Trying to conceptualize how I would compare several values in a list to find the largest value, without using mutable variables.
For example in an imperative language I could simply store a max variable that gets updated every time the iteration finds a larger value in the list. Like such:
max = 0;
for i in list
if i > max
max = i
Now, in functional programming if i had a list, for example [1; 2; 3]
How would I get around the issue of using a max variable?
The easy answer would be to use let maxValue = List.max theList.
If you were wanting to 'roll your own' without using an explicitly mutable variable, the obvious way is to use a recursive function. Personally, I would define it like so:
let listMax theList =
let rec maxHelper remainingList maxSoFar =
match remainingList with
| [] -> maxSoFar
| h :: t ->
if h > maxSoFar then
maxHelper t h
else
maxHelper t maxSoFar
maxHelper theList (List.head theList)
Note that this implementation as presented would throw an exception with an empty input list (also, I haven't actually tested this, so there might be a slight error in there). The reason I have done it this way is that it uses tail recursion, which should mean it's roughly as efficient as a mutable solution, but keeps the complexity of the exposed function signature to the bare minimum.
Alternatively, this could also be done fairly easily with a List.fold call. E.g.
List.fold (fun (nextElem, maxSoFar) ->
if nextElem > maxSoFar then nextElem else maxSoFar) (List.head theList) theList
Same proviso about not having tested it applies to this too.
In both of the presented cases, this could be made more generic to apply to any binary operation that returns a boolean, by using another parameter that is a function which carries out said operation. E.g.
List.fold (fun (nextElem, maxSoFar) ->
if comparatorFunction nextElem maxSoFar then nextElem else maxSoFar)
(List.head theList) theList

comparing length of sublists in a list F#

I'm new to F#, and currently working on a problem where I'm trying to compare the length of sublists inside a list, and returning a boolean.
The program is also supposed to return "false" in case any of the sublists are empty. However as I've been progressing I haven't been able to solve my current problem, even though I somehow see what is wrong (this linked to my experience in the F# language thus far). Hopefully someone can lend me a hand, so I can quickly move on to my next project.
My program so far is as follows:
let projectOne (initList: int list list) =
let mutable lst = initList.[0].Length
let mutable lst1 = ""
let n = initList.Length
for i=1 to n-1 do
if lst = 0 || initList.[i].Length = 0 then
lst1 <- "false"
elif lst <> initList.[i].Length then
lst1 <- "false"
elif
lst = initList.[i].Length then
lst1 <- "true"
lst1
printfn "The sublists are of same lenght: %A" (projectOne [[1;2;3;4];[4;5;6];[6;7;8;9];[5;6;7;8]])
The way I see it is, that right now I am comparing [0] with [i] incrementing with each iteration in my loop, this causes a problem as for the print example, I end my iterations by comparing [0] with [3] and since the 2 sublists are of equal size my function returns "true" which is obviously wrong, since [1] is of length shorter than the rest, hence the result should be "false".
I've tried to solve this by mutating the value of lst, for each iteration, but this again causes a problem if for instance [2] and [3] are same length but [0] and [1] are not, and again it returns "true" even though the output should be "false". (like [[1;2;3];[3;4;5];[6;7];[8;9]])
I can't seem to wrap my head around what I've missed. Since I cant break a loop in F# (at least not in a traditional way like Python), I need to run all my iterations, but I want each iteration to compare with the average of all the previous sublists length (if that makes sense).
What am I missing? :-) I have though of using af List.fold operator to solve the problem, but not sure how I am going to implement this, with the fact that the program also need to check for empty lists.
I can say however I am trying to solve the problem using the metod appropriate to my level og experience thus far. I am sure that several very compact solutions using the pipeline operator |> are available, but I am not yet capable of utilizing these solutions, so I am looking for a simpler perhabs beginners solution.
Thanks in advance.
A more functional way to think about this would be
If all the sublists are empty, they are all the same length
Otherwise, if any of the sublists are empty, they are not of the same length
Otherwise, the lists are all the same length if their tails are all the same length
For example:
let rec projectOne initList =
if List.forall List.isEmpty initList then
true
else if List.exists List.isEmpty initList then
false
else
projectOne (List.map List.tail initList)
Here is another take:
let projectOne lst =
match lst with
| h::t -> t |> List.forall(fun (l:_ list) -> l.Length = h.Length)
| _ -> true
A simple fix of your code could be:
let projectOne (initList: int list list) =
let length = initList.[0].Length
let mutable result = length <> 0
let n = initList.Length
for i=1 to n-1 do
result <- result && initList.[i].Length = length
result
It still operates on a mutable variable which is undesirable in functional programming and it is inefficient in that it searches all lists even if a wrong length has been found.
Another - more functional - solution could be:
let haveEqualLength lists =
let length = lists |> List.head |> List.length
length <> 0 && lists |> List.tail |> List.tryFind (fun l -> l.Length <> length) = None

How to make this loop more functional without bringing too much overheads

for i in a..b do
res <- res * myarray.[i]
res
Do I have to use like
Array.fold (*) 1 (Array.sub myarray a (b - a + 1))
, which I believe is rather slow and not that concise?
Don't know if you'll find it any better, but you could do:
Seq.fold (fun r i -> r * myarray.[i]) 1 {a .. b}
Daniel's solution is pretty neat and I think it should be nearly as efficient as the for loop, because it does not need to clone the array.
If you wanted a more concise solution, then you can use indexer instead of Array.sub, which does need to clone some part of the array, but it looks quite neat:
myarray.[a .. b] |> Seq.fold (*) 1
This clones a part of the array because the slicing operation returns an array. You could define your own slicing operation that returns the elements as seq<'T> (and thus does not clone the whole array):
module Array =
let slice a b (arr:'T[]) =
seq { for i in a .. b -> arr.[i] }
Using this function, you could write:
myarray |> Array.slice a b |> Seq.fold (*) 1
I believe this more directly expresses the functionality that you're trying to implement. As always with performance - you should measure the performance to see if you need to make such optimizations or if the first version is fast enough for your purpose.
If you're concerned with speed then I'd shy away from using seq unless you're prototyping. Either stick with the for loop or rewrite as a recursive function. The example you gave is simplistic and sometimes more complex problems are better represented as recursion.
let rec rangeProduct a b total (array : _[]) =
if a <= b then
rangeProduct (a + 1) b (total * array.[a]) array
else
total
let res = myArray |> rangeProduct a b res
There is no overhead here, it's as fast as possible, there is no mutation, and it's functional.

Return item at position x in a list

I was reading this post While or Tail Recursion in F#, what to use when? were several people say that the 'functional way' of doing things is by using maps/folds and higher order functions instead of recursing and looping.
I have this function that returns the item at position x in a list:
let rec getPos l c = if c = 0 then List.head l else getPos (List.tail l) (c - 1)
how can it be converted to be more functional?
This is a primitive list function (also known as List.nth).
It is okay to use recursion, especially when creating the basic building blocks. Although it would be nicer with pattern matching instead of if-else, like this:
let rec getPos l c =
match l with
| h::_ when c = 0 -> h
| _::t -> getPos t (c-1)
| [] -> failwith "list too short"
It is possible to express this function with List.fold, however the result is less clear than the recursive version.
I'm not sure what you mean by more functional.
Are you rolling this yourself as a learning exercise?
If not, you could just try this:
> let mylist = [1;2;3;4];;
> let n = 2;;
> mylist.[n];;
Your definition is already pretty functional since it uses a tail-recursive function instead of an imperative loop construct. However, it also looks like something a Scheme programmer might have written because you're using head and tail.
I suspect you're really asking how to write it in a more idiomatic ML style. The answer is to use pattern matching:
let rec getPos list n =
match list with
| hd::tl ->
if n = 0 then hd
else getPos tl (n - 1)
| [] -> failWith "Index out of range."
The recursion on the structure of the list is now revealed in the code. You also get a warning if the pattern matching is non-exhaustive so you're forced to deal with the index too big error.
You're right that functional programming also encourages the use of combinators like map or fold (so called points-free style). But too much of it just leads to unreadable code. I don't think it's warranted in this case.
Of course, Benjol is right, in practice you would just write mylist.[n].
If you'd like to use high-order functions for this, you could do:
let nth n = Seq.take (n+1) >> Seq.fold (fun _ x -> Some x) None
let nth n = Seq.take (n+1) >> Seq.reduce (fun _ x -> x)
But the idea is really to have basic constructions and combine them build whatever you want. Getting the nth element of a sequence is clearly a basic block that you should use. If you want the nth item, as Benjol mentioned, do myList.[n].
For building basic constructions, there's nothing wrong to use recursion or mutable loops (and often, you have to do it this way).
Not as a practical solution, but as an exercise, here is one of the ways to express nth via foldr or, in F# terms, List.foldBack:
let myNth n xs =
let step e f = function |0 -> e |n -> f (n-1)
let error _ = failwith "List is too short"
List.foldBack step xs error n

cons operator (::) in F#

The :: operator in F# always prepends elements to the list. Is there an operator that appends to the list? I'm guessing that using # operator
[1; 2; 3] # [4]
would be less efficient, than appending one element.
As others said, there is no such operator, because it wouldn't make much sense. I actually think that this is a good thing, because it makes it easier to realize that the operation will not be efficient. In practice, you shouldn't need the operator - there is usually a better way to write the same thing.
Typical scenario: I think that the typical scenario where you could think that you need to append elements to the end is so common that it may be useful to describe it.
Adding elements to the end seems necessary when you're writing a tail-recursive version of a function using the accumulator parameter. For example a (inefficient) implementation of filter function for lists would look like this:
let filter f l =
let rec filterUtil acc l =
match l with
| [] -> acc
| x::xs when f x -> filterUtil (acc # [x]) xs
| x::xs -> filterUtil acc xs
filterUtil [] l
In each step, we need to append one element to the accumulator (which stores elements to be returned as the result). This code can be easily modified to use the :: operator instead of appending elements to the end of the acc list:
let filter f l =
let rec filterUtil acc l =
match l with
| [] -> List.rev acc // (1)
| x::xs when f x -> filterUtil (x::acc) xs // (2)
| x::xs -> filterUtil acc xs
filterUtil [] l
In (2), we're now adding elements to the front of the accumulator and when the function is about to return the result, we reverse the list (1), which is a lot more efficient than appending elements one by one.
Lists in F# are singly-linked and immutable. This means consing onto the front is O(1) (create an element and have it point to an existing list), whereas snocing onto the back is O(N) (as the entire list must be replicated; you can't change the existing final pointer, you must create a whole new list).
If you do need to "append one element to the back", then e.g.
l # [42]
is the way to do it, but this is a code smell.
The cost of appending two standard lists is proportional to the length of the list on the left. In particular, the cost of
xs # [x]
is proportional to the length of xs—it is not a constant cost.
If you want a list-like abstraction with a constant-time append, you can use John Hughes's function representation, which I'll call hlist. I'll try to use OCaml syntax, which I hope is close enough to F#:
type 'a hlist = 'a list -> 'a list (* a John Hughes list *)
let empty : 'a hlist = let id xs = xs in id
let append xs ys = fun tail -> xs (ys tail)
let singleton x = fun tail -> x :: tail
let cons x xs = append (singleton x) xs
let snoc xs x = append xs (singleton x)
let to_list : 'a hlist -> 'a list = fun xs -> xs []
The idea is that you represent a list functionally as a function from "the rest of the elements" to "the final list". This works great if you are going to build up the whole list before you look at any of the elements. Otherwise you'll have to deal with the linear cost of append or use another data structure entirely.
I'm guessing that using # operator [...] would be less efficient, than appending one element.
If it is, it will be a negligible difference. Both appending a single item and concatenating a list to the end are O(n) operations. As a matter of fact I can't think of a single thing that # has to do, which a single-item append function wouldn't.
Maybe you want to use another data structure. We have double-ended queues (or short "Deques") in fsharpx. You can read more about them at http://jackfoxy.com/double-ended-queues-for-fsharp
The efficiency (or lack of) comes from iterating through the list to find the final element. So declaring a new list with [4] is going to be negligible for all but the most trivial scenarios.
Try using a double-ended queue instead of list. I recently added 4 versions of deques (Okasaki's spelling) to FSharpx.Core (Available through NuGet. Source code at FSharpx.Core.Datastructures). See my article about using dequeus Double-ended queues for F#
I've suggested to the F# team the cons operator, ::, and the active pattern discriminator be made available for other data structures with a head/tail signature.3

Resources