It looks like you're trying to re-implement takeWhile
(or possibly a bugged filter
), so we could simply set
select_where_true :: (Double -> Bool) -> [Double] -> [Double]
select_where_true = takeWhile
But anyway, there are several problems with your code.
The syntax error you got is because you're using the wrong syntax for guards in a
case
. The correct syntax iscase ... of pattern | guard -> ... | ... -> ...
Fixing that reveals a type error in your code. You're trying to use
++
to prepend an element to a list, but++
concatenates two lists. To prepend an element, use:
instead. See: What is the difference between ++ and : in Haskell?With that fixed, the code compiles, but there is a bug: it fails on the empty list, or on lists with more than one element:
> select_where_true is_neg [] *** Exception: S.hs:(2,1)-(5,66): Non-exhaustive patterns in function select_where_true > select_where_true is_neg [1,2] *** Exception: S.hs:(2,1)-(5,66): Non-exhaustive patterns in function select_where_true
This is because you're unintentionally doing pattern matching here:
select_where_true is_neg [a] = ... ^^^
This is a pattern which only matches lists with exactly one element. To match any list, simply get rid of the brackets. You'll have to get rid of the brackets in
case [a] of ...
as well.
Fixing all of these problems, we end up with
select_where_true :: (Double -> Bool) -> [Double] -> [Double]
select_where_true is_neg a = case a of
[] -> []
x:xs | (is_neg x) == False -> []
| (is_neg x) == True -> x : (select_where_true is_neg xs)
Finally, some style suggestions:
- Most of the parentheses are unnecessary. Function application has higher precedence than any operator.
- Never write
expr == True
orexpr == False
. Useexpr
ornot expr
instead. - If the guards cover all cases, you can replace the last one with
otherwise
. A case expression with guards like this is somewhat awkward. It's often easier to write multiple equations instead:
select_where_true :: (Double -> Bool) -> [Double] -> [Double] select_where_true is_neg [] = [] select_where_true is_neg (x:xs) | is_neg x = x : select_where_true is_neg xs | otherwise = []