2015-11-12 57 views
1

使用庫函數,定義一個函數halve :: [a]→([a],[a]) 將一個偶數長度的列表分成兩半。例如:haskell的一半功能

> halve [1, 2, 3, 4, 5, 6] 
([1, 2, 3], [4, 5, 6]) 

到目前爲止我有什麼是

halve :: [a] -> ([a],[a]) 
halve = (\xs -> case xs of 
     [] -> ([],[]) 
     xs -> take ((length xs) `div` 2) xs) 

,它是錯誤的,因爲XS - >取((長x)div 2)僅XS顯示列表的前半部分..請幫助我繼續下去,以便它顯示列表的後半部分。

+1

http://hackage.haskell.org/package/base-4.8.1.0/docs/Prelude.html#v:splitAt – interjay

+0

它得到正確上半年'take',但也許你需要它的對手'drop'。 – Mephy

+0

相關:http://stackoverflow.com/questions/27090347/haskell-novice-trouble-with-splitting-a-list-in-half – Jubobs

回答

1

感謝評論一些解決方案。我解決它......這裏是

first_halve :: [a] -> [a] 
first_halve = (\xs -> case xs of 
      [] -> [] 
      xs -> take ((length xs) `div` 2) xs) 

second_halve :: [a] -> [a] 
second_halve = (\xs -> case xs of 
      [] -> [] 
      xs -> drop ((length xs) `div` 2) xs) 

halve :: [a] -> ([a],[a]) 
halve = (\xs -> case xs of 
      [] -> ([],[]) 
      xs -> (first_halve xs, second_halve xs)) 
+0

使用['splitAt'](http://hackage.haskell.org/package/base-4.8.1.0/docs/Prelude.html#v:splitAt)會比分別調用'take'和'drop'更高效並計算兩次列表的長度。根據您的要求,您甚至可能根本不需要計算列表的長度。 – Jubobs

+0

除了使用'splitAt'的好建議,我還建議仔細考慮你的病例陳述。明確檢查'[]'尋址的關注點是什麼?如果您不檢查,您預測會出錯嗎? (然後,當然,這個好的科學後續問題是,這樣做是錯誤的嗎?) –