[英]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])
,因此您可以通过将Int
和String
替换为类型参数a
和b
来安全地泛化该函数:
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.