Haskell-如何使用递归将列表拆分为n个长子部分

时间:2018-10-26 13:57:41

标签: haskell

以下代码给出了基本的想法。我想通过递归将其扩展到列表的其余部分,但是使用where语法只会给出没有能力的代码。我尝试使用@done命名列表的其余部分,但没有成功。我仍在通过这段代码学习Haskell,所以我宁愿不使用任何简单的解决方案,例如splitAt函数等。

splitEv :: Int -> [a] -> [[a]]
splitEv n [] = []
splitEv n (x:xs) = [take n (x:xs)] ++ [(take n(drop n (x:xs)))]

1 个答案:

答案 0 :(得分:2)

最后一行应为

 splitEv n xs = [take n xs] ++ (splitEv n (drop n xs))

在公式的后半部分,对列表的其余部分(列表的前n个元素除外)调用splitEv。这将一直持续到列表为空。

使用@chi评论

编辑
几乎没有优化是可能的。
在第二行中,n不必用_代替。
在第三行:可以代替++使用。更优化了。也可以减少括号。

splitEV  _ [] = []
splitEV n xs = take n xs:(splitEV n $ drop n xs) 

:和++ 之间的区别(在@chepner注释的帮助下)。
的签名:

  (:) :: a -> [a] -> [a]

而++是

  (++) :: [a] -> [a] -> [a]

:用于在顶部添加单个元素,而++用于连接两个列表。只要有可能,就使用:,因为它更加优化。将其视为在链表的开头添加元素。您只需要调整head元素。
这仅是一个隐喻,在幕后可能会发生更多的事情。