简体   繁体   English

Haskell:从具有静态元素的元组和列表创建元组列表

[英]Haskell: Create a list of tuples from a tuple with a static element and a list

Need to create a list of tuples from a tuple with a static element and a list. 需要从具有静态元素和列表的元组创建一个元组列表。 Such as: 如:

(Int, [String]) -> [(Int, String)]

Feel like this should be a simple map call but am having trouble actually getting it to output a tuple as zip would need a list input, not a constant. 感觉这应该是一个简单的map调用,但实际上很难让它输出一个元组,因为zip需要一个列表输入,而不是一个常量。

I think this is the most direct and easy to understand solution (you already seem to be acquainted with map anyway): 我认为这是最直接,最容易理解的解决方案(无论如何,您似乎已经熟悉map了):

f :: (Int, [String]) -> [(Int, String)]
f (i, xs) = map (\x -> (i, x)) xs

(which also happens to be the desugared version of [(i, x) | x < xs] , which Landei proposed) (它也是Landei提出的[(i, x) | x < xs]的简化版本)

then 然后

Prelude> f (3, ["a", "b", "c"])
[(3,"a"),(3,"b"),(3,"c")]

This solution uses pattern matching to "unpack" the tuple argument, so that the first tuple element is i and the second element is xs . 此解决方案使用模式匹配来“解压缩”元组参数,以便第一个元组元素是i ,第二个元素是xs It then does a simple map over the elements of xs to convert each element x to the tuple (i, x) , which I think is what you're after. 然后,它对xs的元素进行简单map ,以将每个元素x转换为元组(i, x) ,我想这就是您想要的。 Without pattern matching it would be slightly more verbose: 如果没有模式匹配,它将变得更加冗长:

f pair = let i  = fst pair  -- get the FIRST element
             xs = snd pair  -- get the SECOND element
         in map (\x -> (i, x)) xs

Furthermore: 此外:

The algorithm is no way specific to (Int, [String]) , so you can safely generalize the function by replacing Int and String with type parameters a and b : 该算法不是特定于(Int, [String]) ,因此您可以通过将IntString替换为类型参数ab来安全地泛化该函数:

f :: (a, [b]) -> [(a, b)]
f (i, xs) = map (\x -> (i, x)) xs

this way you can do 这样你可以做

Prelude> f (True, [1.2, 2.3, 3.4])
[(True,1.2),(True,2.3),(True,3.4)]

and of course if you simply get rid of the type annotation altogether, the type (a, [b]) -> [(a, b)] is exactly the type that Haskell infers (only with different names): 当然,如果您完全摆脱了类型注释,则类型(a, [b]) -> [(a, b)]正是Haskell推断的类型(仅使用不同的名称):

Prelude> let f (i, xs) = map (\x -> (i, x)) xs
Prelude> :t f
f :: (t, [t1]) -> [(t, t1)]

Bonus: you can also shorten \\x -> (i, x) to just (i,) using the TupleSections language extension: 奖励:您还可以使用TupleSections语言扩展TupleSections \\x -> (i, x)缩短为(i,)

{-# LANGUAGE TupleSections #-}

f :: (a, [b]) -> [(a, b)]
f (i, xs) = map (i,) xs

Also, as Ørjan Johansen has pointed out, the function sequence does indeed generalize this even further, but the mechanisms thereof are a bit beyond the scope. 而且,正如ØrjanJohansen所指出的那样,函数sequence的确确实将其进一步推广了,但是其机制略微超出了范围。

For completeness, consider also cycle , 为了完整起见,还请考虑cycle

f i = zip (cycle [i])

Using foldl , 使用foldl

f i = foldl (\a v -> (i,v) : a ) []

Using a recursive function that illustrates how to divide the problem, 使用说明如何划分问题的递归函数,

f :: Int -> [a] -> [(Int,a)]
f _ [] = []
f i (x:xs) = (i,x) : f i xs

列表理解将是非常直观和可读的:

f (i,xs) = [(i,x) | x <- xs]

Do you want the Int to always be the same, just feed zip with an infinite list. 您是否希望Int始终保持相同,只需用无限列表zip You can use repeat for that. 您可以为此repeat

f i xs = zip (repeat i) xs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM