Haskell,从列表元组中提取两个列表

时间:2014-10-06 05:26:56

标签: list haskell tuples

我正在使用2个辅助函数进行“合并排序”。第一个辅助函数将列表拆分为一个列表,将奇数和偶数索引放在单独的列表中。

Example: [1,2,3,4,5,6]
Returns: ([1,3,5],[2,4,6])

第二个辅助函数假定列表已排序并合并它们。

我将使用这两个函数实现一个未排序列表的合并排序。

我有这个非常低效的部分,基本上分裂(长度 - 1)* 2次并合并列表(长度 - 1)次。

   sort length (z:zs)
        | length == 0 = (z:zs)
        | otherwise   = sort (length - 1) (merge (fst (split(z:zs))) (snd (split(z:zs)))

我正在调用split两次以获得与第一次拆分相同的信息,并且我没有足够的递归(每个列表只是一个单例,然后将它们全部合并)。

如何递归单例并同时拉出元组的两个元素?

提前感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:2)

您可以使用uncurrymerge转换为非咖喱函数,并将split(z:zs)作为参数传递:

sort (length - 1) $ uncurry merge $ split (z:zs)

uncurry函数将a -> b -> c类型的函数转换为(a, b) -> c类型的函数。在您的情况下,merge的类型为[a] -> [a] -> [a],而uncurry merge的类型为([a], [a]) -> [a],而([a], [a])的返回类型为split

或者,您只需使用letwhere子句来引用split的结果:

let (left, right) = split (z:zs)
in sort (length - 1) $ merge left right

是改进版的:

let res = split (z:zs)
in sort (length - 1) $ merge (fst res) (snd res)

作为旁注,您的sort功能不正确。你的定义是:

sort length (z:zs) = ...

但是这只匹配非空列表。如果案件length == 0永远不会发生,那么这也是毫无用处的。

您对sort的定义是考虑空案例的原因:

sort _ [] = []
sort length (z:zs) = ...