2016-12-17 59 views
1

我是Haskell的新手。我知道擁抱已經老了,不再支持,但我的大學仍然使用它。
這裏是我的代碼:
Haskell:按奇數和偶數排序列表

gio n = jako n ++ tazo n 

jako [] = [] 
jako (a:b) = if a `mod` 2 == 1 then a:jako (tail b) else jako (tail b) 

tazo [] = [] 
tazo (a:b) = if a `mod` 2 == 0 then a:tazo (tail b) else tazo (tail b) 

我試圖做的是採取一個列表,並返回甚至清單團結奇列表。例如gio [1,2,3,4,5,6,7,8,9] = [1,3,5,7,9,2,4,6,8] 但在我的情況下,它返回Program error: {tail []}或者如果原始列表長度是偶數,則它只返回奇數部分列表。例如:gio [1,2,3,4,5,6,7,8] = [1,3,5,7]它似乎在調用jako n時會改變列表,它會通過引用或類似的方式傳遞列表。什麼可以改變來實現目標? P.S我不需要一些庫函數來做到這一點,它需要通過使用我的函數來完成。謝謝。

+0

請使用'CTRL-k'格式化代碼塊。並且總是爲你所問的任何Haskell函數添加類型簽名,這使得更容易看到發生了什麼(對我們和你來說都是這樣!)。 – leftaroundabout

+0

對不起,下次我會考慮這個問題 – Rasty

+0

您是否嘗試刪除所有'tail b'並直接使用'b'?這是因爲'b'已經是輸入的尾部了。 – chi

回答

1

當輸入爲a:b,該b部分是尾部,所以沒有必要使用tail b - 這將是尾部的最尾部,它可以引發一個運行時錯誤時,尾部b是空的(即輸入的長度爲1)。此外,即使錯誤不是問題,再次使尾部跳過列表的下一個元素,這是錯誤的。

的解決方案是從代碼中移除的尾巴:

gio n = jako n ++ tazo n 

jako [] = [] 
jako (a:b) = if a `mod` 2 == 1 then a:jako b else jako b 

tazo [] = [] 
tazo (a:b) = if a `mod` 2 == 0 then a:tazo b else tazo b 
0
gio :: Integral a => [a] -> [a] 
gio n = jako n ++ tazo n 
    where 
    jako [] = [] 
    jako (x:xs) 
     | isOdd x  = x:jako xs 
     | otherwise = jako xs 
    tazo [] = [] 
    tazo (x:xs) 
     | isEven x = x:tazo xs 
     | otherwise = tazo xs 
    isEven n = mod n 2 == 0 
    isOdd n = mod n 2 /= 0