是否有一个函数可以展平嵌套的元素列表? [英] Is there a function to flatten a nested list of elements?

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

问题描述

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

How can I flatten a nested list like this:

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

推荐答案

因为没有其他人给出过这个,所以可以定义一个函数,通过使用 MultiParamTypeClasses 来展平任意深度的列表.我实际上并没有发现它有用,但希望它可以被认为是一个有趣的黑客.我从 Oleg 的多变量函数实现中得到了这个想法.

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天全站免登陆