Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 无跨步功能_List_Haskell - Fatal编程技术网

List 无跨步功能

List 无跨步功能,list,haskell,List,Haskell,我最近需要跨越一个列表,以便只窥视一些元素。这算是一个过滤函数,但并不是那么简单。但首先,这是一个跨越 跨距列表(或任何可遍历类型)与折叠列表相同,但会丢弃一些经常遇到的元素(关于跨距值)。我们拾取一个元素,然后要拾取的下一个值将是下一个值。例如,如果我们在跨步值设置为0的情况下对列表进行跨步,那么实际上会使列表保持不变。如果我们跨过一个列表,我们得到两个元素中的一个: stride 0 [1..10] == [1..10] stride 1 [1..10] == [1,3,5,7,9] str

我最近需要跨越一个列表,以便只窥视一些元素。这算是一个过滤函数,但并不是那么简单。但首先,这是一个跨越

跨距列表(或任何可遍历类型)与折叠列表相同,但会丢弃一些经常遇到的元素(关于跨距值)。我们拾取一个元素,然后要拾取的下一个值将是下一个值。例如,如果我们在跨步值设置为0的情况下对列表进行跨步,那么实际上会使列表保持不变。如果我们跨过一个列表,我们得到两个元素中的一个:

stride 0 [1..10] == [1..10]
stride 1 [1..10] == [1,3,5,7,9]
stride 2 [1..10] == [1,4,7,10]
我查看了
数据.列表
,没有发现任何可以跨越列表的内容。这就是为什么我写了一个函数来跨越我的——和你的!——材料:

import Data.DList

-- for Data.List
stride :: (Num a, Eq a) => a -> [b] -> [b]
stride s = toList . snd . foldl (\(sa,xa) x -> if sa == s then (0,xa `snoc` x) else (sa+1,xa)) (s,fromList [])
你可以像上面那样使用它。
是否可以提议将其作为
数据列表
模块的一部分?我认为它会有很大帮助。

此函数并不能完全满足您的需要,但您可以将
stride
函数建立在它的基础上:

chunksOf :: Int -> [a] -> [[a]]
chunksOf n = takeWhile (not . null) . map (take n) . iterate (drop n)
现在,您的步幅函数可能如下所示:

stride :: Int -> [a] -> [a]
stride n = map head . chunksOf (n + 1)

在这里使用
head
很好,因为
takeWhile(not.null)
确保子列表永远不能为空。

此函数不能完全满足您的需要,但您可以将
stride
函数建立在它的基础上:

chunksOf :: Int -> [a] -> [[a]]
chunksOf n = takeWhile (not . null) . map (take n) . iterate (drop n)
现在,您的步幅函数可能如下所示:

stride :: Int -> [a] -> [a]
stride n = map head . chunksOf (n + 1)

在这里使用
head
很好,因为
takeWhile(not.null)
确保子列表永远不能为空。

一个同样适用于无限列表且效率更高的简单实现是

stride :: Int -> [a] -> [a]
stride s = go
  where
    go (x:xs) = x : go (drop s xs)
    go _      = []
如果您想将其用于除
Int
以外的其他类型,请使用它

import Data.List

stride :: Integral i => i -> [a] -> [a]
stride s = go
  where
    go (x:xs) = x : go (genericDrop s xs)
    go _      = []
在我看来,对非整数类型这样做毫无意义

是否可以提议将其作为
数据列表
模块的一部分

是的,那是可能的,就libraries@haskell.org邮件列表


然而,我认为它不会被接受。有用性太小,无法将其添加到
base
包中。最好将其添加到另一个包中。也许将其包含在中是最好的。

一个更简单的实现,也可以在无限列表上工作,并且效率更高

stride :: Int -> [a] -> [a]
stride s = go
  where
    go (x:xs) = x : go (drop s xs)
    go _      = []
如果您想将其用于除
Int
以外的其他类型,请使用它

import Data.List

stride :: Integral i => i -> [a] -> [a]
stride s = go
  where
    go (x:xs) = x : go (genericDrop s xs)
    go _      = []
在我看来,对非整数类型这样做毫无意义

是否可以提议将其作为
数据列表
模块的一部分

是的,那是可能的,就libraries@haskell.org邮件列表

然而,我认为它不会被接受。有用性太小,无法将其添加到
base
包中。最好将其添加到另一个包中。也许最好将其包含在中。

或者使用该软件包,您可以:

>stridingOf l n = (elementsOf l ((==0) . (flip mod (n + 1))))
>striding = stridingOf traverse
>stride n = toListOf striding

>stride 1 [1..10]
[1,3,5,7,9]
编写stridingOf而不是仅仅是striding的一点额外工作允许在文本和ByTestRing上轻松使用,并且在没有软件包的情况下重写要困难得多

#镜头

或者使用该软件包,您可以:

>stridingOf l n = (elementsOf l ((==0) . (flip mod (n + 1))))
>striding = stridingOf traverse
>stride n = toListOf striding

>stride 1 [1..10]
[1,3,5,7,9]
编写stridingOf而不是仅仅是striding的一点额外工作允许在文本和ByTestRing上轻松使用,并且在没有软件包的情况下重写要困难得多



#镜头

没错
chunksOf
是可以添加的函数,
stride
可以基于它。
chunksOf
的另一种实现可以在这篇博文中找到:我总是说:寻找组合解决方案。我特别喜欢这种方法,因为它使用了构图。Daniel的实现和您的实现都没有利用这一点。编辑:这也确保了它是适当的懒惰。毫无疑问,您的
chunksOf
实现是优雅的!这正是我在写我的博客文章时所寻找的(但找不到,请看“未来工作”评论)。这是一个展开器<代码>chunksOf n=takeWhile(非.null)。unbover(Just.splitAt n)您实际上可以通过以下简短的代码片段来实现
stride
本身的
unbover
,但我并不喜欢它:
stride n=unbover(\xs'->dox:xs完全正确!
chunksOf
是可以添加的函数,而
stride
可以基于它。在这篇博文中可以找到
chunksOf
的另一种实现:我总是说:使用组合解决方案。我特别喜欢这种方法,因为它使用了组合。Dani和Dani都不喜欢el的实现和你的实现都没有利用它。编辑:这也确保了它是适当的懒惰。毫无疑问,你对
chunksOf
的实现是优雅的!这正是我在写我的博客文章时所寻找的(并且找不到,请参阅“未来工作”备注)。这是一个展开器!
chunksOf n=takeWhile(not.null)。展开器(Just.splitAt n)
您实际上可以通过以下简短的代码片段来实现
stride
本身的
unfover
,但我并不喜欢它:
stride n=unfover(\xs'->do x:xs好吧,它对
RealFrac
s来说是有意义的,基本上是一个更高效的
\s l->[l!!round x | x这样的东西可能确实有意义,我没有想到。如果你看一下链接的实现,它从0开始一步一步地计数,直到
sa==s
,如果
s
是整数,它只会产生比初始元素更多的元素。哇,忘了
drop
函数,好主意:)嗯,这对于
RealFrac
s是有意义的,它基本上是一个更高效的
\s l->[l!!round x | x这样的东西可能确实有意义,我没有想到。如果你看一下链接的实现,它从0开始一步一步地计数,直到
sa==s
,如果
s
是整数,它只会产生比初始元素更多的元素。哇,忘了
drop
函数,好主意:)为什么不使用
stride n xs=chunk(n+1)xs>>=take 1
?这几乎不是一个问题——这是唯一合适的问题