2013-05-13 107 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 ...,沒有括號。