将列表转换为具有Haskell中的折叠的列表的列表 [英] Transform a list into a list of lists with fold in haskell

查看:59
本文介绍了将列表转换为具有Haskell中的折叠的列表的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有此代码:

fromList :: Int -> [Int] -> [[Int]]
fromList y = takeWhile (not.null) . map (take y) . iterate (drop y) 

此功能的示例:->fromList 4 [1..19]

[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19]]

如何折叠显示代码?

推荐答案

这是使用 folder 的非常优雅的解决方案:

Here's a pretty elegant solution using foldr:

fromList :: Int -> [a] -> [[a]]
fromList n = foldr (\v a ->
    case a of
        (x:xs) -> if length x < n then (v:x):xs else [v]:a
        _ -> [[v]]
    ) []

本质上,累加器是最终值,对于列表中的每个值,它都会检查是否还有空间将其放入现有块中,如果没有,则将其放入新块中.可悲的是,由于使用了 folder ,多余的元素被放置在左侧而不是右侧.可以通过对 foldl (或 foldl')使用稍微慢一点(也许更丑陋)的方法来解决此问题:

Essentially, the accumulator is the end value, and for each value in the list it checks if there's still space to put it in an existing chunk, and if there isn't then it puts it in a new chunk. Sadly, due to using foldr, extra elements are put on the left side instead of the right side. This can be fixed by using a slightly slower (and maybe slightly uglier) approach with foldl (or foldl'):

fromList :: Int -> [a] -> [[a]]
fromList _ [] = []
fromList n (x:xs) = reverse $ foldl (\a@(y:ys) v ->
    if length y < n
        then (y ++ [v]):ys
        else [v]:a
    ) [[x]] xs

这篇关于将列表转换为具有Haskell中的折叠的列表的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆