I’m very new to Haskell (and functional programming in general), and I’m trying some basic exercises to try to get an understanding of the language. I’m writing a “naive” prime number checker that divides each number under the input to check if there is any remainder. The only constructs I’ve learned so far are comprehension lists and recursive functions, so I’m constrained to that. Here’s what I’m trying:
isprime 1 = False
isprime 2 = True
isprime n = isprimerec n (n-1)
isprimerec _ 1 = False
isprimerec n t = if (n `rem` t) == 0 then False else isprimerec n (n-1)
The intention is that the user would use isprime n. Then isprime would use isprimerec to determine if the number is prime. It’s a pretty round-about way of doing it, but I don’t know any other way with my limited knowledge of Haskell.
Here’s what happens when I try this:
isprimerec 10 9
Runs forever. I have to use Ctrl+C to stop it.
isprimerec 10 5
Returns False. The else part is never evaluated, so the function never calls itself.
I’m not sure why this is happening. Also, is this anywhere near close to how a Haskell programmer would approach this problem? (And I don’t mean checking primality, I know this isn’t the way to do it. I’m just doing it this way as an exercise).
The problem is in this line
You use
(n - 1)as the second argument where it should be(t - 1). A further point, I think you want theisprimerec _ 1case= True.As to your more general question of whether or not this is idiomatic, I think you’re on the right track.
ghcihas a decent command line debugger. I found this by putting your code in a file, loading it, and then issuing the command:break isprimerec. I then called your function and stepped through it with:step.