haskell一种优雅的方法来从无限的数字列表中过滤(减少)重复序列 [英] haskell elegant way to filter (reduce) sequences of duplicates from infinte list of numbers
问题描述
这是一个生成无限随机数列表的函数
This is a function that produces an infinite list of random 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,..]
I want to reduce sequences for duplicate elements into one element e.g [2,3,4,1,7,7,7,3,4,1,1,1,3,..] -> [2,3,4,1,7,3,4,1,3,..]
因此,我需要[Int]->中的一些精美功能"f" .[Int]就是这样做的.另外,它必须懒惰地与无限列表一起使用,所以如果我运行
So, I need some elegant function "f" from [Int] -> [Int] that do this. Also, it must work with an infinite list lazily, so if I run
f values
它不能实时挂起并输出数据
it must not hang and output data in real-time
推荐答案
You can work with group :: Eq a => [a] -> [[a]]
to make a list of groups. So for the given sample data, this will generate:
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
的第一个元素,我们知道该元素存在,因为否则它将永远不会构造一个新的组:
Then we can for each sublist only yield the first element with head
, we know that such element exists, since otherwise it would never have constructed a new group in the first place:
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
定义为:
This thus means that you can define f
as:
import Data.List(group)
f :: Eq a => [a] -> [a]
f = map head . group
这也适用于无限列表.例如,如果我们以无限的 5
s列表结束列表,则它将处理该列表直到该5,然后继续寻找新值:
This works on infinite lists as well. For example if we end the list with an infinite list of 5
s, then it processes the list until that five and keeps looking for a new value:
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
or we can make use of the group :: (Foldable f, Eq a) => f a -> [NonEmpty a]
of Data.List.NonEmpty
:
import Data.List.NonEmpty(group)
import qualified Data.List.NonEmpty as NE
f :: Eq a => [a] -> [a]
f = map NE.head . group
这篇关于haskell一种优雅的方法来从无限的数字列表中过滤(减少)重复序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!