Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - defining a function with guards inside a 'where'

Tags:

I'm just starting out at teaching myself Haskell. This code is supposed to do prime factorisation:

divides :: Integer -> Integer -> Bool divides small big = (big `mod` small == 0)  lowestDivisor :: Integer -> Integer lowestDivisor n = lowestDivisorHelper 2 n     where lowestDivisorHelper m n         | (m `divides` n) = m  -- these should belong to lowestDivisorHelper         | otherwise = lowestDivisorHelper (m+1) n  primeFactors :: Integer -> [Integer] primeFactors 1 = [] primeFactors n     | n < 1 = error "Must be positive"     | otherwise = let m = lowestDivisor n                   in m:primeFactors (n/m) 

I get a parse error on the commented line. I think my problem might be that lowestDivisorHelper has guards, but the compiler doesn't know whether the guards belong to lowestDivisorHelper or lowestDivisor. How do I get around this?

I should add that I didn't want to define the helper function at the top level in order to hide the implementation detail. Importing the file shouldn't take the helper function with it.

like image 697
Benjamin Hodgson Avatar asked Nov 11 '12 00:11

Benjamin Hodgson


People also ask

Where are Haskell guards?

Haskell guards are used to test the properties of an expression; it might look like an if-else statement from a beginner's view, but they function very differently. Haskell guards can be simpler and easier to read than pattern matching .

What is guard expression in Haskell?

A guard is basically a boolean expression. If it evaluates to True, then the corresponding function body is used. If it evaluates to False, checking drops through to the next guard and so on. If we call this function with 24.3, it will first check if that's smaller than or equal to 18.5.

What is where in Haskell?

Definition on Haskell Where Function. Haskell where is not a function rather it is a keyword that is used to divide the more complex logic or calculation into smaller parts, which makes the logic or calculation easy to understand and handle.

What does == mean in Haskell?

The == is an operator for comparing if two things are equal. It is quite normal haskell function with type "Eq a => a -> a -> Bool". The type tells that it works on every type of a value that implements Eq typeclass, so it is kind of overloaded.


1 Answers

lowestDivisor :: Integer -> Integer lowestDivisor n = lowestDivisorHelper 2 n where    lowestDivisorHelper m n         | (m `divides` n) = m  -- these should belong to lowestDivisorHelper         | otherwise = lowestDivisorHelper (m+1) n 

You need to start a new statement with your helper function for the guards to be sufficiently indented by comparison. (And you also forgot an argument, n.) This would also work:

lowestDivisor :: Integer -> Integer lowestDivisor n = lowestDivisorHelper 2 n      where    lowestDivisorHelper m n         | (m `divides` n) = m  -- these should belong to lowestDivisorHelper         | otherwise = lowestDivisorHelper (m+1) n 

but this doesn't:

lowestDivisor :: Integer -> Integer lowestDivisor n = lowestDivisorHelper 2 n    where lowestDivisorHelper m n         | (m `divides` n) = m  -- these should belong to lowestDivisorHelper         | otherwise = lowestDivisorHelper (m+1) n 

The key point is that the | has to be further to the right than the function name.

In general, starting a new line continues the previous one as long as it is further to the right. The guards have to continue on from the function name.

like image 196
AndrewC Avatar answered Sep 27 '22 22:09

AndrewC