1

我想圍繞Haskell的語法包紮頭腦。守衛和匿名函數列表

這個問題很簡單,邏輯解決。我必須分解一個正整數和負整數的列表,並將它們分組,使得

[1,2,3,-1,-2,-3,1,2,3]變成[[1,2, 3],[ - 1,-2,-3],[1,2,3]]

我想使用更高階的函數,foldr可以用一個匿名函數arguements。

這是我到目前爲止。

split = foldr (\ x y -> if (x > 0) 
         then if (head (head y)) < 0 
          then [x] : y 
          else x : head y --error here 
         else if (x < 0) 
         then if (head (head y)) > 0 
          then [x] : y 
          else x : head y 
         else y 
       ) 
       [[]] 

這是錯誤我得到

Occurs check: cannot construct the infinite type: a0 = [a0] 
    In the first argument of `(:)', namely `x' 
    In the expression: x : head y 
    In the expression: 
     if (head (head y)) < 0 then [x] : y else x : head y 

我有兩個問題。

1)爲什麼我在第7行出現類型錯誤?

我這不是連接來整數列表(頭Y)

2)你怎麼寫出來的使用警衛下述條件的整數(X)?我試圖做到這一點,但我一直收到parsing error at '|'

回答

1

你只是想保持tail y。在

foldr (\ x y -> if (x > 0) 
        then if (head (head y)) < 0 
         then [x] : y 
         else x : head y 

你有x :: (Num a, Ord a) => ay :: (Num a, Ord a) => [[a]]head y :: (Num a, Ord a) => [a]

因此,忘記tail y削減了一層[]。所述else分支應該是

else (x:head y) : tail y 
在外 if的兩個分支

但是,之後你的函數有兩個語義問題。

首先,您不要將head y爲空的情況視爲,當到達列表的末尾時會導致異常,其次,它無法在無限列表上工作,因爲組合函數不會在' t在第二個參數已知之前構造任何結果。如果後者是一個問題,你可以找到一個足夠懶惰的組合函數in this answer

+0

啊。非常感謝!如果說'擁有'x'頭部',我不會在某種意義上「返回」列表的列表,而只是列表? – ali

+0

是的,這是問題所在。 –

2
  1. 一個函數只能有一個混凝土返回類型和[x] : y是從x : head y不同的類型。

  2. 它可能更容易將其與takeWhiledropWhile寫:

    split l = split' (if head l > 0 then (>) else (<)) l 
        where split' op [] = [] 
         split' op l = takeWhile (`op` 0) l : split (dropWhile (`op` 0) l)