brabec
brabec

Reputation: 4740

F# function type mismatch

What's wrong with my test function?

let divisorOf(d, n) = n % d = 0

let notDivisible(d, n) = not (divisorOf(d, n))

let rec test(a, b, c) = function
  | (a, b, _) when (a > b) -> true
  | (a, b, c) -> notDivisible(a, c) && test(a + 1, b, c)

I'm getting a compiler error that the expression on line 7 has function type, not bool.

(7,40): error FS0001: This expression was expected to have type
    bool    
but here has type
    'a * 'a * 'b -> bool    

Upvotes: 1

Views: 208

Answers (2)

Onorio Catenacci
Onorio Catenacci

Reputation: 15343

John's answer is completely right but for the sake of others who might read this, this is a bit more idiomatic form of the code you posted:

let divisorOf d n = n % d = 0

let notDivisible d n = not <| divisorOf d n
//Could also be let notDivisible d n = not(divisorOf d n)

let rec test =
    function
    | (a, b, _) when (a > b) -> true
    | (a, b, c) -> (notDivisible a c) && test (a + 1, b, c)

I only bother to point this out because on both divisorOf and notDivisible you've declared a tuple for the argument and that's a common issue when people who aren't used to writing curried arguments start writing F#.

I only post this as an answer because it's a bit too long for a comment.

Upvotes: 2

John Palmer
John Palmer

Reputation: 25526

When you use the keyword function you are creating an implict lambda. It is inferred that the input to this is a int*int*int. To fix this just get change

let rec test(a,b,c) =

to

let rec test =

If you want to be explicit with the arguments you could also write it as

let rec test(d, e, f) = match (d,e,f) with //change letters to avoid variable hiding
  | (a, b, _) when (a > b) -> true
  | (a, b, c) -> notDivisible(a, c) && test(a + 1, b, c)

Upvotes: 5

Related Questions