斯卡拉 – 如何表达[42 | x == y]有理解吗?
我有一些代码片段,我生成多个列表(通过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中它也是一个对象(但可能也是优化的).我认为做这么简单的工作效率很低. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |