2
votes

I have been attempting the Eulers in F#* and am currently on #5. My problem is using a function that takes more than one parameter in a pipeline operation.

This function correctly returns whether the first parameter is divisible by every member of an array which is the second parameter:

let isDivisibleBy seq n =
    seq
    |> Seq.forall (fun x -> n % x = 0)

isDivisibleBy [|1 .. 10|] 2520 //true

However, the following statement does not work:

Seq.initInfinite
    |> Seq.find isDivisibleBy [|1 .. 10|]  

I get the following error:

error FS0001: The type '((int -> 'c) -> seq<'c>) -> 'd' is not compatible with the type 'seq<'a>'

*"2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?"

1

1 Answers

5
votes

Short answer:

You're missing parentheses and first argument of Seq.initInfinite. Correct code:

Seq.initInfininte id
|> Seq.find (isDivisibleBy [|1..10|])

Explanation

In expression Seq.find isDivisibleBy [|1 .. 10|] you're trying to call function Seq.find with two arguments, isDivisibleBy and [|1 .. 10|]. And then you're trying to use the resulting value as second argument of the pipe (|>) operator. Your code is equivalent to this (just make each call a separate step):

let a = Seq.find isDivisibleBy [|1 .. 10|]
Seq.initInfinite |> a

Which is obviously incorrect.

From the rest of your code, I infer that what you probably wanted to do was to partially apply the function isDivisibleBy to argument [|1 .. 10|], and then pass the resulting value to Seq.find, like this:

let b = isDivisibleBy [|1 .. 10|]
let a = Seq.find b
Seq.initInfinite |> a

But this still won't compile, because Seq.initInfinite takes one argument - a function mapping indexes to elements of generated sequence, - but you provide no arguments:

let b = isDivisibleBy [|1 .. 10|]
let a = Seq.find b
let c = Seq.initInfinite (fun x -> x)
c |> a

Removing intermediate lets from the above code and replacing the redundant lambda fun x -> x with id, we get the final answer:

Seq.initInfininte id
|> Seq.find (isDivisibleBy [|1..10|])