高阶函数,输入“|”解析错误

时间:2013-05-13 15:29:04

标签: haskell higher-order-functions parse-error

这是我的代码:

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.

有人喜欢告诉我我的代码有什么问题吗?

感谢所有能给我一些建议的人。

3 个答案:

答案 0 :(得分: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 = []
    

答案 1 :(得分:2)

卫兵不去那里。请改用案例陈述。如case isNeg x of

答案 2 :(得分: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 ...,没有括号。