2015-09-13 32 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

相关问题