0

I have the following code, which implements the sieve or Eratosthenes:

primeSieve :: Int -> [Int] -- Returns a list of primes up to upperbound
primeSieve upperbound = filter[2..upperbound] 
  where filter ls indx = 
    let divisor = (ls!!indx)
    let filtered = [x | x <- ls, x `mod` divisor /= 0]
    if divisor*divisor >= last filtered
      then filtered
      else filter filtered (indx+1)

I get a parse error on line 4, "possible incorrect indentation or mismatched brackets".

Why is this?

0

2 Answers 2

2

I believe you wanted to write filter with a do-notation. You could just add a do just after the filter ls indx =. However, this code being pure (i.e. non monadic), I would recommend this syntax:

primeSieve :: Int -> [Int] -- Returns a list of primes up to upperbound
primeSieve upperbound = filter [2..upperbound]
  where
    filter ls indx =
        let divisor = (ls!!indx)
            filtered = [x | x <- ls, x `mod` divisor /= 0]
        in if divisor*divisor >= last filtered
          then filtered
          else filter filtered (indx+1)

... but your code gives me the following error:

<file>:13:25:
Couldn't match expected type `[Int]'
            with actual type `Int -> [Int]'
Probable cause: `filter' is applied to too few arguments
In the expression: filter [2 .. upperbound]
In an equation for `primeSieve':
    primeSieve upperbound
      = filter [2 .. upperbound]
      where
          filter ls indx
            = let ...
              in
                if divisor * divisor >= last filtered then
                    filtered
                else
                    filter filtered (indx + 1)
Failed, modules loaded: none.

I think you meant to pass 0 as a second argument to filter:

primeSieve :: Int -> [Int] -- Returns a list of primes up to upperbound
primeSieve upperbound = filter [2..upperbound]
  where
    filter ls indx =
        let divisor = (ls!!indx)
            filtered = [x | x <- ls, x `mod` divisor /= 0]
        in if divisor*divisor >= last filtered
          then filtered
          else filter filtered (indx+1)
Sign up to request clarification or add additional context in comments.

2 Comments

What is the meaning of the "in if"?
This is just a let ... in clause followed by a if expression. Nothing magic here.
1

The issue is the indentation of the definition of filter which is smaller than what it shoul be. The important part is

where filter ls indx = 
  let divisor = (ls!!indx)

where the let starts 4 characters before the filter on the line above. That triggers the syntax error. To fix it you can indent more the filter definition

where filter ls indx = 
        let divisor = (ls!!indx)

a more common format is

where
  filter ls indx = 
    let divisor = (ls!!indx)

because in this way you don't indent too much.

You can find more information about indentation on the haskell wiki which contains some nice visual examples about this kind of errors.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.