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.

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

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

4

3 回答 3

7

看起来您正在尝试重新实现takeWhile(或者可能是错误的filter),所以我们可以简单地设置

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

但无论如何,您的代码存在几个问题。

  • 您得到的语法错误是因为您在case. 正确的语法是

    case ... of
        pattern | guard -> ...
                | ...   -> ...
    
  • 修复在您的代码中显示类型错误的问题。您正在尝试使用++元素添加到列表中,但++将两个列表连接起来。要添加元素,请:改用。请参阅: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 = []
    
于 2013-05-13T16:31:34.937 回答
2

卫兵不去那里。请改用 case 语句。如在case isNeg x of

于 2013-05-13T15:37:09.087 回答
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 ...的意思是,没有括号。

于 2013-05-13T16:07:43.973 回答