In F#, nearly everything is an expression, so for example

i <- i + 2

is an expression, that when evaluated, updates the mutable variable i and results in the unit value "()". So you can say

let x = i <- i + 2

and x has type unit. Similar, if-then-else is an expression you can say stuff like

let nextN = if N%2=0 then N/2 else 3*N+1

where both the 'then' and 'else' branch resolve to numbers. In your code, the 'then' and 'else' branches have different types, which is not allowed. (Note also there is no 'return' statement that would let you 'return false' and break out of the while loop early. The recursive version is easy to code and will more easily allow you to write an efficient early exit, if so desired.)

By on 12/10/2008 12:29 AM ()

Here is another version without recursion:

let checkPrime2 n =

seq { for i in [2..(n/2)] do

if i*i < n then yield i }

|> Seq.exists (fun m -> n % m = 0)

|> not

Note that I'm not sure if you can tell the seq - builder to exit (normaly you will want to stop the seqeuence if i*i >= n - so I do the test and only yield if i*i < n - to save some iterations I only test values up to n/2 - so you run the % - test for all numbers up to sqrt(n) but blow some CPU time by just going up to n/2 without doing something)

If you are not familiar with seq-Constructors: the seq { ... } just constructs a Sequence of values from 2 to sqrt(n) - this sequence is passed to the Seq.exists function that searches for a value in the seqence that satisfies n%m = 0 and stops as soon as it has found any - this of course tells you if n is NOT a prime so I just have to negate the answer with the "|> not" (put the previous value into the boolean not function)

Maybe you can help me too: how can I get my codeblocks in there without the nasty empty lines ??

By on 12/9/2008 9:53 PM ()

The Problem is, that a if .... then ... else ... statement must return a value of the same type in each branch. But you don't really need a return statement - the structure is that you can put a bunch of expressions in there but you have to take care that each expression but the last has type UNIT meaning no return value at all - the result of the last statement is then returned.

In your example the then branch returns a boolean (false) and the else branch returns UNIT (because i <- i+2 doesn't return anything.

This might look like a major lack of the language because you can't write "efficient" code like you used to (for example you are trying to leave the while loop early to make faster code).

F# is not really meant to be played with low-level optimization ... saying that here is a simple way to get your code running:

let checkPrime3 n =

let mutable i = 3

let mutable cont = true

while i*i < n && cont = true do

cont <-

if 0=n%i then false

else i <- i+2; true

done

cont

Please note that my syntax need the #light switch ;)

Of course this is NOT functional style and looks somewhat ugly so you might want to write

#light

let checkPrime n =

let rec innerCheck n m =

if m*m >= n then true else

if n % m = 0 then false else innerCheck n (m+1)

innerCheck n 2

so this uses recursion but is almost the same as your are trying to do - hope this is helpfull

By on 12/9/2008 9:37 PM ()

That explains it - thanks for the help, everyone.

By on 12/10/2008 6:32 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper