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

lib*_*bra 2 haskell parse-error higher-order-functions

这是我的代码:

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
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

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

test.hs:5:18: parse error on input `|'
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

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

感谢任何能给我一些建议的人.

ham*_*mar 7

看起来你正试图重新实现takeWhile(或者可能是一个bug filter),所以我们可以简单地设置

select_where_true :: (Double -> Bool) -> [Double] -> [Double]
select_where_true = takeWhile
Run Code Online (Sandbox Code Playgroud)

但无论如何,你的代码有几个问题.

  • 你得到的语法错误是因为你使用了错误的语法来保护case.正确的语法是

    case ... of
        pattern | guard -> ...
                | ...   -> ...
    
    Run Code Online (Sandbox Code Playgroud)
  • 修复会在代码中显示类型错误.您尝试使用++元素添加到列表中,但++连接两个列表.要预先添加元素,请:改用.请参阅:在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
    
    Run Code Online (Sandbox Code Playgroud)

    这是因为你在这里无意中进行了模式匹配:

    select_where_true is_neg [a] = ...
                             ^^^
    
    Run Code Online (Sandbox Code Playgroud)

    这是一种仅匹配具有一个元素的列表的模式.要匹配任何列表,只需删除括号.你也必须摆脱括号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)
Run Code Online (Sandbox Code Playgroud)

最后,一些风格的建议:

  • 大多数括号都是不必要的.函数应用程序的优先级高于任何运算符.
  • 永远不要写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 = []
    
    Run Code Online (Sandbox Code Playgroud)