haskell 从无限数字列表中过滤(减少)重复序列的优雅方法
haskell elegant way to filter (reduce) sequences of duplicates from infinte list of numbers
这是一个生成无限随机数列表的函数
import System.Random
values :: [Int]
values = map fst $ scanl (\(r, gen) _ -> randomR (1,10) gen) (randomR (1,10) (mkStdGen 1)) $ repeat ()
我想将重复元素的序列减少为一个元素,例如
[2,3,4,1,7,7,7,3,4,1,1,1,3,..] -> [2,3,4,1,7,3,4,1,3 ,..]
所以,我需要一些来自 [Int] -> [Int] 的优雅函数 "f" 来执行此操作。
此外,它必须懒惰地处理无限列表,所以如果我 运行
f values
一定不能挂,实时输出数据
您可以使用 group :: Eq a => [a] -> [[a]]
来制作群组列表。因此对于给定的示例数据,这将生成:
Prelude> import Data.List(group)
Prelude Data.List> group [2,3,4,1,7,7,7,3,4,1,1,1,3]
[[2],[3],[4],[1],[7,7,7],[3],[4],[1,1,1],[3]]
然后我们可以为每个子列表只产生第一个元素head
,我们知道这样的元素存在,否则它永远不会首先构造一个新组:
Prelude Data.List> map head (group [2,3,4,1,7,7,7,3,4,1,1,1,3])
[2,3,4,1,7,3,4,1,3]
这意味着您可以将 f
定义为:
import Data.List(group)
f :: Eq a => [a] -> [a]
f = map head . group
这也适用于无限列表。例如,如果我们以 5
的无限列表结束列表,那么它会处理列表直到那五个并继续寻找新值:
Prelude Data.List> map head (group (2 : 3 : 4 : 1 : 7 : 7 : 7 : 3 : 4 : 1 : 1 : 1 : 3 : repeat 5))
[2,3,4,1,7,3,4,1,3,5
或者我们可以利用 Data.List.NonEmpty
的 group :: (Foldable f, Eq a) => f a -> [NonEmpty a]
:
import Data.List.NonEmpty(group)
import qualified Data.List.NonEmpty as NE
f :: Eq a => [a] -> [a]
f = map NE.head . group
这是一个生成无限随机数列表的函数
import System.Random
values :: [Int]
values = map fst $ scanl (\(r, gen) _ -> randomR (1,10) gen) (randomR (1,10) (mkStdGen 1)) $ repeat ()
我想将重复元素的序列减少为一个元素,例如 [2,3,4,1,7,7,7,3,4,1,1,1,3,..] -> [2,3,4,1,7,3,4,1,3 ,..]
所以,我需要一些来自 [Int] -> [Int] 的优雅函数 "f" 来执行此操作。 此外,它必须懒惰地处理无限列表,所以如果我 运行
f values
一定不能挂,实时输出数据
您可以使用 group :: Eq a => [a] -> [[a]]
来制作群组列表。因此对于给定的示例数据,这将生成:
Prelude> import Data.List(group)
Prelude Data.List> group [2,3,4,1,7,7,7,3,4,1,1,1,3]
[[2],[3],[4],[1],[7,7,7],[3],[4],[1,1,1],[3]]
然后我们可以为每个子列表只产生第一个元素head
,我们知道这样的元素存在,否则它永远不会首先构造一个新组:
Prelude Data.List> map head (group [2,3,4,1,7,7,7,3,4,1,1,1,3])
[2,3,4,1,7,3,4,1,3]
这意味着您可以将 f
定义为:
import Data.List(group)
f :: Eq a => [a] -> [a]
f = map head . group
这也适用于无限列表。例如,如果我们以 5
的无限列表结束列表,那么它会处理列表直到那五个并继续寻找新值:
Prelude Data.List> map head (group (2 : 3 : 4 : 1 : 7 : 7 : 7 : 3 : 4 : 1 : 1 : 1 : 3 : repeat 5))
[2,3,4,1,7,3,4,1,3,5
或者我们可以利用 Data.List.NonEmpty
的 group :: (Foldable f, Eq a) => f a -> [NonEmpty a]
:
import Data.List.NonEmpty(group)
import qualified Data.List.NonEmpty as NE
f :: Eq a => [a] -> [a]
f = map NE.head . group