2013-05-13 100 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 == Trueexpr == False。改为使用exprnot 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 2013-05-14 01:44:42

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 ...,没有括号。