加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

斯卡拉 – 如何表达[42 | x == y]有理解吗?

发布时间:2020-12-16 09:06:05 所属栏目:安全 来源:网络整理
导读:我有一些代码片段,我生成多个列表(通过for comprehensions),然后连接它们.有一些单元素列表,但这不起作用.在 Haskell中,我会做类似的事情 [42 | i == j] 等价的是 (do guard (i == j) return 42) :: [Int] 要么 (guard (i == j) = _ - return 1) :: [Int]
我有一些代码片段,我生成多个列表(通过for comprehensions),然后连接它们.有一些单元素列表,但这不起作用.在 Haskell中,我会做类似的事情

[42 | i == j]

等价的是

(do guard (i == j)
    return 42) :: [Int]

要么

(guard (i == j) >>= _ -> return 1) :: [Int]

在斯卡拉我试过

for (if i == j) yield 42

但它说“非法启动简单模式”.

In an answer to what Scala’s yield is作者说’Scala’“用于理解”等同于Haskell的“do”符号.

此外,在Scala website上它说“理解具有(枚举)产生e的形式,其中枚举是指以分号分隔的枚举器列表.枚举器是引入新变量的生成器,或者是过滤器”.但很明显,事实并非如此,因为过滤器似乎只能在发电机之后才能使用.

目前我使用

if (i == j) List(42) else Nil

对于这种特殊情况,我可能不会更喜欢for comprehension语法,而只是使用if-then-else代替.在Haskell中,由于与数学集合构造符号的相似性,它看起来相当不错.

我的问题不是关于风格,而是更多关于技术细节:为什么Haskell和Scala之间的这种特殊情况存在差异?为什么不(如果i == j)收益率为42?

解决方法

最接近的等价于[42 | i == j]可能是(x < - List(42),如果i == j)yield x. for(if i == j)yield 42是非法的,因为过滤器(如果是部分)必须跟随某个生成器(在我的例子中x < - List(42)). Scala language specification州(6.19对于理解和循环):

句法:

Expr1       ::= ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’)
                  {nl} [‘yield’] Expr
Enumerators ::= Generator {semi Enumerator}
Enumerator  ::= Generator
                | Guard
                | ‘val’ Pattern1 ‘=’ Expr
Generator   ::= Pattern1 ‘<-’ Expr [Guard]
Guard       ::= ‘if’ PostfixExpr

如您所见,枚举器中至少需要一个生成器.

编辑:

顺便说一句,我认为如果(i == j)List(42)其他Nil是正确的事情,因为它不是Haskell.它很干净,而且很可能更快,因为它只构造一次列表而不调用任何其他方法.

我的例子是由编译器翻译成List(42)withFilter(x => i == j)map(x => x)(它实际上可能是优化的,我不确定)并且可以缩写为List( 42)滤波器(x => i == j).您可以看到它构造初始列表,而不是调用创建新列表的方法,并且此方法采用匿名函数,在Scala中它也是一个对象(但可能也是优化的).我认为做这么简单的工作效率很低.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读