有没有一个函数来扁平化一个嵌套的元素列表? [英] Is there a function to flatten a nested list of elements?

查看:110
本文介绍了有没有一个函数来扁平化一个嵌套的元素列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何平铺这样的嵌套列表:

How can I flatten a nested list like this:

[1, 2, 3, 4] == flatten [[[1,2],[3]],[[4]]]


推荐答案

由于没有人给出这个,所以可以通过使用MultiParamTypeClasses来定义一个函数来平坦化任意深度的列表。我其实没有发现它有用,但希望它可以被认为是一个有趣的黑客。

Since nobody else has given this, it is possible to define a function which will flatten lists of an arbitrary depth by using MultiParamTypeClasses. I haven't actually found it useful, but hopefully it could be considered an interesting hack. I got the idea from Oleg's polyvariadic function implementation.

{-# LANGUAGE MultiParamTypeClasses, OverlappingInstances, FlexibleInstances #-}

module Flatten where

class Flatten i o where
  flatten :: [i] -> [o]

instance Flatten a a where
  flatten = id

instance Flatten i o => Flatten [i] o where 
  flatten = concatMap flatten

现在,如果您加载并运行在ghci中:

Now if you load it and run in ghci:

*Flatten> let g = [1..5]
*Flatten> flatten g :: [Integer]
[1,2,3,4,5]
*Flatten> let h = [[1,2,3],[4,5]]
*Flatten> flatten h :: [Integer]
[1,2,3,4,5]
*Flatten> let i = [[[1,2],[3]],[],[[4,5],[6]]]
*Flatten> :t i
i :: [[[Integer]]]
*Flatten> flatten i :: [Integer]
[1,2,3,4,5,6]



注意通常需要提供结果类型注释,否则ghc不能找出递归地应用 flatten 类方法的地方。然而,如果你使用了一个单态类型的函数,那就足够了。

Note that it's usually necessary to provide the result type annotation, because otherwise ghc can't figure out where to stop recursively applying the flatten class method. If you use a function with a monomorphic type that's sufficient however.

*Flatten> :t sum
sum :: Num a => [a] -> a
*Flatten> sum $ flatten g

<interactive>:1:7:
    No instance for (Flatten Integer a0)
      arising from a use of `flatten'
    Possible fix: add an instance declaration for (Flatten Integer a0)
    In the second argument of `($)', namely `flatten g'
    In the expression: sum $ flatten g
    In an equation for `it': it = sum $ flatten g
*Flatten> let sumInt = sum :: [Integer] -> Integer
*Flatten> sumInt $ flatten g
15
*Flatten> sumInt $ flatten h
15

这篇关于有没有一个函数来扁平化一个嵌套的元素列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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