2013-05-13 4 views
2

Вот мой код:Функция более высокого порядка, ошибка синтаксического анализа на входе `| '

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 

А вот сообщение об ошибке:

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

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

Любой любит, чтобы сказать мне, что случилось с моим кодом?

Спасибо за каждого, кто может мне помочь.

ответ

7

Похоже, вы пытаетесь повторно реализовать takeWhile (или, возможно, прослушивается filter), так что мы могли бы просто установить

select_where_true :: (Double -> Bool) -> [Double] -> [Double] 
select_where_true = takeWhile 

Но в любом случае, есть несколько проблем с вашим кодом.

  • Ошибка синтаксиса у вас есть, потому что вы используете неправильный синтаксис для охранников в case. Правильный синтаксис

    case ... of 
        pattern | guard -> ... 
          | ... -> ... 
    
  • Закрепление, который показывает ошибку типа в коде. Вы пытаетесь использовать ++, чтобы добавить элемент к списку, но ++ объединяет два списков. Чтобы добавить элемент, используйте вместо этого :. См: What is the difference between ++ and : in Haskell?

  • При этом неподвижная, код компилируется, но есть ошибка: она не на пустом списке, или в списках с более чем один элемент:

    > 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 
    

    Это потому, что вы «повторно непреднамеренно делать по шаблону здесь:

    select_where_true is_neg [a] = ... 
             ^^^ 
    

    Это шаблон, который соответствует только списки с одного элемента. Чтобы соответствовать любому списку, просто избавиться от скобок. Вы также должны избавиться от скобок в case [a] of ....

Закрепление все эти проблемы, мы в конечном итоге с

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) 

Наконец, некоторые предложения типа:

  • Большинство скобки не нужны. Функциональное приложение имеет более высокий приоритет, чем любой оператор.
  • Никогда не пишите expr == True или expr == False. Вместо этого используйте expr или not expr.
  • Если защитные устройства покрывают все случаи, вы можете заменить последний otherwise.
  • Выражение в случае с такими стражами несколько неудобно. Часто бывает проще написать несколько уравнений вместо:

    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 = [] 
    
+0

Thx у так много, я следовал, что у сказал и установил ее. – libra

2

Охранники не ходят туда. Вместо этого используйте оператор case. как в case isNeg x of

1

вы можете написать это:

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   -> [] 

совпадению, первый случай невозможен; а во втором (x:xs)=[a] означает x=a, xs=[]. Возможно, вы имели в виду select_where_true is_neg a = case a of ..., без скобок.