我想获得 Raku 中惰性但有限的 Seq 的最后一个元素,例如:
my $s = lazy gather for ^10 { take $_ };
Run Code Online (Sandbox Code Playgroud)
以下内容不起作用:
say $s[* - 1];
say $s.tail;
Run Code Online (Sandbox Code Playgroud)
这些可以工作,但看起来不太惯用:
say (for $s<> { $_ }).tail;
say (for $s<> { $_ })[* - 1];
Run Code Online (Sandbox Code Playgroud)
在保持原始 Seq 惰性的同时,最惯用的方法是什么?
是否有一种惯用的方法来确定LazySeq是否包含元素?从Clojure 1.5开始,调用contains?抛出IllegalArgumentException:
IllegalArgumentException contains? not supported on type: clojure.lang.LazySeq
clojure.lang.RT.contains (RT.java:724)
Run Code Online (Sandbox Code Playgroud)
在1.5之前,据我所知,它总是返回false.
我知道调用contains?LazySeq可能永远不会返回,因为它可能是无限的.但是如果我知道它不是并且不关心它是否被热切评估呢?
我想出的是:
(defn lazy-contains? [col key]
(not (empty? (filter #(= key %) col))))
Run Code Online (Sandbox Code Playgroud)
但它感觉不太对劲.有没有更好的办法?
我有一个函数生成称为函数的惰性序列.
如果我运行代码:
(map a-function a-sequence-of-values)
Run Code Online (Sandbox Code Playgroud)
它按预期返回一个惰性序列.
但是当我运行代码时:
(mapcat a-function a-sequence-of-values)
Run Code Online (Sandbox Code Playgroud)
它打破了我的功能的懒惰.事实上,它将代码转换为
(apply concat (map a-function a-sequence-of-values))
Run Code Online (Sandbox Code Playgroud)
因此,在连接这些值之前,需要从地图中实现所有值.
我需要的是一个函数,它可以根据需要连接map函数的结果,而不事先预先知道所有的map.
我可以为此修改一个函数:
(defn my-mapcat
[f coll]
(lazy-seq
(if (not-empty coll)
(concat
(f (first coll))
(my-mapcat f (rest coll))))))
Run Code Online (Sandbox Code Playgroud)
但我不敢相信clojure没有做过任何事情.你知道clojure有这样的功能吗?只有少数人和我有同样的问题?
我还找到了一个处理相同问题的博客:http://clojurian.blogspot.com.br/2012/11/beware-of-mapcat.html
当我们使用超出数组边界的索引对数组进行切片时,我们得到的结果是 undefined (Any)
当我们传递与惰性列表相同的切片索引时,我们将获得数组/列表的现有值(并且仅此而已):
my @a = ^5;
say @a[^10]; # (0 1 2 3 4 (Any) (Any) (Any) (Any) (Any))
say @a[lazy ^10]; # (0 1 2 3 4)
Run Code Online (Sandbox Code Playgroud)
很明显,切片索引的惰性会影响结果。
试图理解事物的方式并作为概念证明,我编写了我的切片机制的简单版本:
my @a = ^5;
my @s1 = ^10;
my @s2 = lazy ^10;
sub postcircumfix:<-[ ]-> (@container, @index) {
my $iter = @index.iterator;
gather {
loop {
my $item := $iter.pull-one;
if $item =:= IterationEnd {
last;
}
with @container[$item] {
take @container[$item]
} else {
@index.is-lazy ?? …Run Code Online (Sandbox Code Playgroud) 我有一个函数应该采取懒惰的seq并返回一个未实现的懒惰seq.现在我想写一个单元测试(在test-is btw中)以确保结果是一个未实现的延迟序列.
我是Haskell的新手,我正试图以流处理方式实现Euler的Sieve.
当我查看关于素数的Haskell Wiki页面时,我发现了一些神秘的流优化技术.在3.8维基的线性合并中:
primesLME = 2 : ([3,5..] `minus` joinL [[p*p, p*p+2*p..] | p <- primes'])
where
primes' = 3 : ([5,7..] `minus` joinL [[p*p, p*p+2*p..] | p <- primes'])
joinL ((x:xs):t) = x : union xs (joinL t)
Run Code Online (Sandbox Code Playgroud)
它说
" 根据Melissa O'Neill的代码,这里引入了双素数反馈,以防止不必要的记忆,从而防止内存泄漏."
怎么会这样?我无法弄清楚它是如何工作的.
primes haskell sieve-of-eratosthenes lazy-sequences space-leak
这主要是为了了解Raku有多棒。
题
是否有内置方法可以获取列表并无限期地循环遍历它,例如生成惰性列表
a, b, c, a, b, c, ...
Run Code Online (Sandbox Code Playgroud)
出(a, b, c)?列表文档中的任何内容似乎都没有明显的作用。
可能的解决方案
我至少能想到一对。
更实际的方法是映射 @array[<variable> mod length-of-@array]惰性范围0..Inf。在perl6REPL 中:
> my @ar=<a b c>
[a b c]
> (0..Inf).map({ @ar[$_ % @ar.elems] }).[0..100]
(a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b …Run Code Online (Sandbox Code Playgroud) 我正在Clojure中编写一个简单的桌面搜索引擎,以此来了解有关该语言的更多信息.到目前为止,我的程序文本处理阶段的表现非常糟糕.
在文本处理期间,我要:
这是代码:
(ns txt-processing.core
(:require [clojure.java.io :as cjio])
(:require [clojure.string :as cjstr])
(:gen-class))
(defn all-files [path]
(let [entries (file-seq (cjio/file path))]
(filter (memfn isFile) entries)))
(def char-val
(let [value #(Character/getNumericValue %)]
{:a (value \a) :z (value \z)
:A (value \A) :Z (value \Z)
:0 (value \0) :9 (value \9)}))
(defn is-ascii-alpha-num [c]
(let [n (Character/getNumericValue c)]
(or (and (>= n (char-val :a)) (<= n (char-val :z)))
(and (>= n (char-val :A)) (<= n (char-val :Z))) …Run Code Online (Sandbox Code Playgroud) 我正在阅读O'reilly Clojure编程书,它在其关于延迟序列的部分中说了以下内容:
延迟序列可以(尽管非常罕见)知道它的长度,因此在没有实现其内容的情况下将其作为计数结果返回.
我的问题是,这是如何完成的以及它为何如此罕见?
遗憾的是,本书未在本节中指定这些内容.我个人认为,在实现之前知道延迟序列的长度是非常有用的,例如,在同一页面中是使用函数处理的延迟文件序列的示例map.很高兴知道在实现序列之前可以处理多少文件.
为什么我<<loop>>在这里得到一个无限循环 ( ) 运行时错误?
文件反馈.hs:
plus1 :: [Int]->[Int] -- add 1 to input stream
plus1 [] = []
plus1 (x:xs) = (x+1): plus1 xs
to10 :: [Int] -> [Int] -- stop the input stream when it gets to 10
to10 (x:xs) | x < 10 = x : to10 xs
| otherwise = []
to10plus :: [Int] -> ([Int], Int) -- like to10 but also return the count
to10plus (x:xs) | x < 10 = (x, 1) `merge` …Run Code Online (Sandbox Code Playgroud) lazy-sequences ×10
clojure ×5
raku ×3
haskell ×2
rakudo ×2
concat ×1
iterable ×1
list ×1
primes ×1
slice ×1
space-leak ×1
unit-testing ×1