2015-09-13 65 views
3

Haskell是否有內建或慣用的方式來「解開」列表中的元素並將它們作爲函數的單獨參數?如何將Haskell中的列表解壓爲單個參數?

舉例來說,如果我有f :: a -> b -> c -> d -> e是有什麼緊湊像

f (unlist x) 

完成

let x = [1,2,3,4] in f (x!!0) (x!!1) (x!!2) (x!!3) 

,或者至少不那麼「shouty」(太多!!重複)的方式來解壓縮列表通常已知長度(在這種情況下,它可以用作函數的參數)。


基本上就是我在尋找的東西像什麼呢[email protected]@在數學:

f[[email protected]@{1, 2, 3, 4}] 
+2

我不認爲在Haskell的類型系統,鍵入檢查。也許像'unlist1','unlist2','unlist3'等變體一樣。在這種情況下,'unlist3 f [a,b,c] = fabc'並且像'unlist3 fx'一樣使用或者使用中綴來看起來像一個函數「呼叫」。 – Mephy

+3

有[trick](http://okmij.org/ftp/Haskell/polyvariadic.html#polyvar-fn)說服類型系統讓你寫polyvariadic函數。這是相對不平凡和重量級的,所以你不會經常看到它。最着名的用例是['Text.Printf'](http://hackage.haskell.org/package/base-4.8.1.0/docs/Text-Printf.html)。 – duplode

回答

4

它不會是在Haskell類型系統特別有用:

  1. 作爲Mephy指出,每個列表長度需要一個單獨的函數,並且在運行時通過長度錯誤的列表會失敗;
  2. 所有參數必須具有相同的類型。

鑑於此,元組的使用比列表更有意義,因爲它避免了兩個問題;標準庫包括uncurry它做這行的2個參數的功能,你可以通過類比定義uncurry3等:

uncurry3     :: (a -> b -> c -> d) -> ((a, b, c) -> d) 
uncurry3 f (a, b, c)  = f a b c 
+0

有沒有一種方法可以修復我的幼稚方法,使它看起來不像我在喊(它裏面有很多!!!!!!! s!)? – orome

+2

儘管如此,但一般情況下,儘量避免使用'!!',除非必要。例如。使用模式匹配而不是'!!'來訪問小已知索引處的元素:'f a b c d'中的let [a,b,c,d] = [1,2,3,4]。 –

+2

@raxacoricofallapatorius ...並且在大多數情況下訪問* large *已知索引處的元素時,您應該切換到不同的數據結構,因爲'(!!)'超出部分範圍,也是* O(n)*指數。 – duplode

相關問題