在Raku中,如何编写相当于Haskell的跨度函数的等效内容?
在Raku中,如何编写Haskell的span
函数的等效内容?
在haskell中,给定谓词和列表,一个人可以将列表分为两个部分:
- 元素的最长前缀
- 满足谓词列表的剩余
,例如haskell表达式………
span (< 10) [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4]
评估是
([2,2,2,5,5,7],[13,9,6,2,20,4])
如何编写raku等效的Haskell的span
功能?
更新1
基于@chenyf的答案,我开发了以下span
subroutine(稍后的更新反映否定 在span> span
保持忠实所需 Haskell的span
函数 )…
sub span( &predicate, @numberList )
{
my &negatedPredicate = { ! &predicate($^x) } ;
my $idx = @numberList.first(&negatedPredicate):k ;
my @lst is Array[List] = @numberList[0..$idx-1], @numberList[$idx..*] ;
@lst ;
} # end sub span
sub MAIN()
{
my &myPredicate = { $_ <= 10 } ;
my @myNumberList is Array[Int] = [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4] ;
my @result is Array[List] = span( &myPredicate, @myNumberList ) ;
say '@result is ...' ;
say @result ;
say '@result[0] is ...' ;
say @result[0] ;
say @result[0].WHAT ;
say '@result[1] is ...' ;
say @result[1] ;
say @result[1].WHAT ;
} # end sub MAIN
程序输出是…
@result is ...
[(2 2 2 5 5 7) (13 9 6 2 20 4)]
@result[0] is ...
(2 2 2 5 5 7)
(List)
@result[1] is ...
(13 9 6 2 20 4)
(List)
更新2
利用发布到 stackoverflow 有关Raku的nil code> nil
,SubRoutine span
的以下更新的草稿是…
sub span( &predicate, @numberList )
{
my &negatedPredicate = { ! &predicate($^x) } ;
my $idx = @numberList.first( &negatedPredicate ):k ;
if Nil ~~ any($idx) { $idx = @numberList.elems ; }
my List $returnList = (@numberList[0..$idx-1], @numberList[$idx..*]) ;
$returnList ;
} # end sub span
sub MAIN()
{
say span( { $_ == 0 }, [2, 2, 5, 7, 4, 0] ) ; # (() (2 2 5 7 4 0))
say span( { $_ < 6 }, (2, 2, 5, 7, 4, 0) ) ; # ((2 2 5) (7 4 0))
say span( { $_ != 9 }, [2, 2, 5, 7, 4, 0] ) ; # ((2 2 5 7 4 0) ())
} # end sub MAIN
In Raku, how does one write the equivalent of Haskell's span
function?
In Haskell, given a predicate and a list, one can split the list into two parts:
- the longest prefix of elements satisfying the predicate
- the remainder of the list
For example, the Haskell expression …
span (< 10) [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4]
… evaluates to …
([2,2,2,5,5,7],[13,9,6,2,20,4])
How does one write the Raku equivalent of Haskell's span
function?
Update 1
Based on the answer of @chenyf, I developed the following span
subroutine (additional later update reflects negated predicate within span
required to remain faithful to the positive logic of Haskell's span
function) …
sub span( &predicate, @numberList )
{
my &negatedPredicate = { ! &predicate($^x) } ;
my $idx = @numberList.first(&negatedPredicate):k ;
my @lst is Array[List] = @numberList[0..$idx-1], @numberList[$idx..*] ;
@lst ;
} # end sub span
sub MAIN()
{
my &myPredicate = { $_ <= 10 } ;
my @myNumberList is Array[Int] = [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4] ;
my @result is Array[List] = span( &myPredicate, @myNumberList ) ;
say '@result is ...' ;
say @result ;
say '@result[0] is ...' ;
say @result[0] ;
say @result[0].WHAT ;
say '@result[1] is ...' ;
say @result[1] ;
say @result[1].WHAT ;
} # end sub MAIN
Program output is …
@result is ...
[(2 2 2 5 5 7) (13 9 6 2 20 4)]
@result[0] is ...
(2 2 2 5 5 7)
(List)
@result[1] is ...
(13 9 6 2 20 4)
(List)
Update 2
Utilizing information posted to StackOverflow concerning Raku's Nil
, the following updated draft of subroutine span
is …
sub span( &predicate, @numberList )
{
my &negatedPredicate = { ! &predicate($^x) } ;
my $idx = @numberList.first( &negatedPredicate ):k ;
if Nil ~~ any($idx) { $idx = @numberList.elems ; }
my List $returnList = (@numberList[0..$idx-1], @numberList[$idx..*]) ;
$returnList ;
} # end sub span
sub MAIN()
{
say span( { $_ == 0 }, [2, 2, 5, 7, 4, 0] ) ; # (() (2 2 5 7 4 0))
say span( { $_ < 6 }, (2, 2, 5, 7, 4, 0) ) ; # ((2 2 5) (7 4 0))
say span( { $_ != 9 }, [2, 2, 5, 7, 4, 0] ) ; # ((2 2 5 7 4 0) ())
} # end sub MAIN
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我使用
第一个
方法和:k
副词,如下:I use
first
method and:k
adverb, like this:对此完全天真的看法:
创建一个新的
@arr1
,然后将数组复制到@arr2
中。循环,如果谓词是 在数组中的第一个元素满足,那是最后一次。否则,将第一个元素从@arr2
中移开,然后将其推到@arr1
上。测试此问题时:
输出是:
仅出现问题...如果未满足谓词 怎么办?好吧,让我们检查一下列表是否为空或,无法满足谓词以终止循环。
A completely naive take on this:
Create a new
@arr1
and copy the array into@arr2
. Loop, and if the predicate is not met for the first element in the array, it's the last time through. Otherwise, shift the first element off from@arr2
and push it onto@arr1
.When testing this:
The output is:
Only problem here is... what if the predicate isn't met? Well, let's check if the list is empty or the predicate isn't met to terminate the loop.
因此,我认为我会将自己的版本扔进去,因为我认为
分类
可能会有所帮助:MAP
最后是处理谓词永远不会或永远是真的。So I figured I'd throw my version in because I thought that
classify
could be helpful :The
map
at the end is to handle the situation where either the predicate is never or always true.在他的演讲中 105 c ++算法Raku(***)讨论一个几乎可以回答您的问题的功能。我已经对您的问题进行了一些重新分配,但是更改很小。
In his presentation 105 C++ Algorithms in 1 line* of Raku (*each) Daniel Sockwell discusses a function that almost answers your question. I've refactored it a bit to fit your question, but the changes are minor.
Raku的6.e版将发挥新的“ Snip”功能:
Version 6.e of raku will sport the new 'snip' function: