有没有一个函数来扁平化一个嵌套的元素列表? [英] Is there a function to flatten a nested list of elements?
问题描述
如何平铺这样的嵌套列表:
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屋!