Pergunta

Here is my code:

select_where_true :: (Double -> Bool) -> [Double] -> [Double]
select_where_true is_neg [a] = case [a] of
[] -> []
x:xs -> is_neg x 
             |(is_neg x) == False = []
             |(is_neg x) == True = x ++ (select_where_true is_neg xs)


is_neg :: Double -> Bool
is_neg x = x < 0

And here is the error message:

[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:5:18: parse error on input `|'
Failed, modules loaded: none.

Anyone likes to tell me what's wrong with my code?

Thanks for anyone who can good me some advice.

Foi útil?

Solução

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 is

    case ... 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 or expr == False. Use expr or not 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 = []
    

Outras dicas

Guards don't go there. Use a case statement instead. as in case isNeg x of

you can write it like this:

select_where_true :: (Double -> Bool) -> [Double] -> [Double]
select_where_true is_neg [a] = case [a] of
  []                -> []
  (x:xs) | is_neg x -> x ++ (select_where_true is_neg xs)
  oterwise          -> []

coincidentally, the first case is impossible; and in second (x:xs)=[a] means x=a, xs=[]. Perhaps you meant select_where_true is_neg a = case a of ..., without the brackets.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top