0

I have the following code that returns all numbers in the input list within the range given by the first two arguments:

inRange :: Int -> Int -> [Int] -> [Int]
inRange a b xs = [if (x > a && x < b) then x | x <- xs]

and it gives me the following error:

parse error on input '|'

Sorry if I'm asking a stupid question but I really don't know what I'm doing wrong

2
  • 3
    if … then … else …. I'm currently not really capable of providing a well written answer, so here's the short one: [x | x <- xs, x > a, x < b]. Feel free to use it in an answer. Commented Nov 14, 2014 at 11:58
  • I noticed that you had two questions in a row that had to do with incorrect syntax. What resources are you using to learn Haskell? Maybe I could point you at some more to help you learn the syntax better. SO isn't really the place to go when you have syntax problems (a parse error always means it's syntax), those kinds of questions tend to clutter up the site. I'd like to help you learn the syntax, but I don't think SO is the place to be learning it. Let me know what you're currently referencing and I'll try to add several more that should be able to help you out. Commented Nov 14, 2014 at 14:29

2 Answers 2

3

You're missing an else to that if statement. All ifs in haskell have an else too. The reason that an error about | comes up is that the parser is expecting an else, and it found a |.

So either you want

[if (x > a && x < b) then x else ??? | x <- xs]

or you want

[x | x <- xs, x > a, x < b]

Which can in turn be rewritten as

filter (\x -> x > a && x < b) xs
Sign up to request clarification or add additional context in comments.

Comments

0

What you are trying to do is one of the more common ways of using list comprehension.

List comprehension is described in Haskell98 report as having this

aexp    ->  [ exp | qual1 , ... , qualn ]   (list comprehension, n>=1)
qual    ->  pat <- exp  (generator)
|   let decls   (local declaration)
|   exp (guard)

what is means is that you provide between [ and | what you are trying to have as a new list element. This is where you use functions to change your list elements such as [ head a | will make a list of heads of some a

After | come qualifiers. They can be

  • generators (like x <- xs )
  • local declarations
  • or guards

What you need in your case are 2 guards (x > a and x < b) and one generator (x <- xs) so what you need is

[ x | x <- xs , x > a, x < b ]

Some argue that list comprehension is for begginers and should later be substituted with higher order functions like filter and map so in your case you would acutally only need filter

some examples

inRange' a b xs = filter (\ x -> (x > a) && (x < b) ) xs
-- eta reduced version (without using xs)
inRange'' a b = filter (\ x -> (x > a) && (x < b) )

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.