获取元组列表并返回元组

时间:2015-03-31 14:59:55

标签: haskell

我在Haskell中编写一个递归函数,它将元组列表作为输入并返回一个元组。返回的元组的第一部分应该是列表中元组的数量,返回的元组的第二部分应该是列表中每个元组的所有元素。在这里清除它是一个示例运行应该是什么样的:

gather [ (0, [true, true] ), (1, [true, false] ), (2, [false, true]) ]
  returns (3, [true, true, true, false, false, true] )

我对Haskell相当新,但这是我对递归代码的尝试:

gather  [()] = [()]
gather n as = head as : gather n (take n as)
tupList :: [(a)] -> [(a)]
tupList n xs = map (\x -> gather n (take x xs)) [n..]

编译器完全不喜欢这个,有什么建议可以解决这个问题吗?谢谢你的时间!

2 个答案:

答案 0 :(得分:1)

首先让我给你一个工作版本(我希望这不是功课):

gather :: [(a,[b])] -> (Int, [b])
gather xs = (length xs, concatMap snd xs)

现在到你的版本:

首先你没有给出签名,但gather的两个案例已经在参数数量上有所不同(第一个有[()] -> [()]类型,第二个类似Int -> [a] -> [a](你是什么)真正想要的就是我给出的 - 或者我根据你的例子猜测。)

接下来的想法是,我不知道你要对gather做些什么 - 如果你解释你的想法,我会试着让你走上正轨。

根据您的需要tupList,我不知道。

备注

知道你想要一个递归功能 - 但如果作业,这只是首选IMO ...所以我感觉没有给你一个递归版本... ...如果你想要你可以使用递归重写concatMap部分(或length)。

根据您的评论

我认为你想做正确的思考:将问题分成两部分:连接列表和计算项目。

计算项目非常简单:要么使用length,要么重新定义它:

length :: [a] -> Int
length [] = 0
length (_:tl) = 1 + length tl

第一个问题应该是这样的:

concat :: [[a]] -> [a]
concat [] = []
concat (xs:xss) = undefined

也许你可以尝试自己填写(最有可能你使用(++)

如果你将它重写为:

,你可以像我一样做
gather ts = (length ts, concat (map snd ts))

直接来自GHCi:你的例子

λ> gather [(0, [True, True] ), (1, [True, False] ), (2, [False, True])]
(3,[True,True,True,False,False,True])

答案 1 :(得分:0)

这是一个递归版本。它只在输入列表中执行一次传递。做两次独立的通行证往往会导致空间泄漏。

gather xs = g 0 xs 
  where
  g c []         = (c, [])
  g c ((_,ys):r) = (a, ys ++ b) 
                     where 
                     (a,b) = c `seq` g (c+1) r
当我们沿着列表前进时,

seq会导致立即计算计数器。如果没有它,c+1的计算可能会被不必要地延迟。

实际上这是保护的递归。