需要使用静态元素和列表从元组创建元组列表。如:
(Int, [String]) -> [(Int, String)]
感觉这应该是一个简单的map
调用,但实际上遇到输出元组时遇到麻烦,因为zip
需要列表输入,而不是常量。
答案 0 :(得分:4)
我认为这是最直接易懂的解决方案(无论如何你似乎已经熟悉了map
):
f :: (Int, [String]) -> [(Int, String)]
f (i, xs) = map (\x -> (i, x)) xs
(这也恰好是Landei提出的[(i, x) | x < xs]
的desugared版本)
然后
Prelude> f (3, ["a", "b", "c"])
[(3,"a"),(3,"b"),(3,"c")]
此解决方案使用模式匹配来“解包”元组参数,以便第一个元组元素为i
,第二个元素为xs
。然后,它会对map
的元素执行简单的xs
,将每个元素x
转换为元组(i, x)
,我认为这就是您所追求的。没有模式匹配,它会更加冗长:
f pair = let i = fst pair -- get the FIRST element
xs = snd pair -- get the SECOND element
in map (\x -> (i, x)) xs
<强>此外:强>
该算法并非特定于(Int, [String])
,因此您可以使用类型参数Int
和String
替换a
和b
来安全地概括该功能:
f :: (a, [b]) -> [(a, b)]
f (i, xs) = map (\x -> (i, x)) xs
这样你可以做到
Prelude> f (True, [1.2, 2.3, 3.4])
[(True,1.2),(True,2.3),(True,3.4)]
当然,如果你只是简单地删除类型注释,那么类型(a, [b]) -> [(a, b)]
正是Haskell推断的类型(只有不同的名称):
Prelude> let f (i, xs) = map (\x -> (i, x)) xs
Prelude> :t f
f :: (t, [t1]) -> [(t, t1)]
加分:您还可以使用\x -> (i, x)
语言扩展程序将(i,)
简化为TupleSections
:
{-# LANGUAGE TupleSections #-}
f :: (a, [b]) -> [(a, b)]
f (i, xs) = map (i,) xs
另外,正如ØrjanJohansen指出的那样,函数sequence
确实进一步概括了这一点,但其机制有点超出了范围。
答案 1 :(得分:2)
为完整起见,请同时考虑cycle
,
f i = zip (cycle [i])
使用foldl
,
f i = foldl (\a v -> (i,v) : a ) []
使用递归函数说明如何划分问题,
f :: Int -> [a] -> [(Int,a)]
f _ [] = []
f i (x:xs) = (i,x) : f i xs
答案 2 :(得分:2)
列表理解将非常直观和可读:
f (i,xs) = [(i,x) | x <- xs]
答案 3 :(得分:0)
您希望Int
始终相同,只需将zip
与无限列表一起提供。您可以使用repeat
。
f i xs = zip (repeat i) xs