简体   繁体   English

具有零限定符的列表推导(ZF 表达式)

[英]List comprehensions (ZF-expressions) with zero qualifiers

List comprehensions (or ZF-expressions) include a sequence of qualifiers , which can be generators or Boolean-valued expressions ("filter expressions") acting as guards.列表推导式(或 ZF 表达式)包括一系列限定符,它们可以是生成器布尔值表达式(“过滤器表达式”),充当警卫。

A list comprehension with no qualifier – for instance, [1 | ]没有限定符的列表推导式——例如, [1 | ] [1 | ] – is (apparently) valid in Miranda 1 (p. 130) , but is invalid in Haskell 2 , 3 (p. 42) –I tried it in the ghci interpreter– and is (apparently) invalid in Clean 4 . [1 | ] – 在 Miranda 1 (p. 130)中(显然)有效,但在 Haskell 2、3 第 42 页)中无效 – 我在ghci解释器中尝试过 – 并且(显然)在 Clean 4中无效。

(Of course, we could simulate it by adding a True guard, for instance [1 | True] . But this is more verbose.) (当然,我们可以通过添加一个True保护来模拟它,例如[1 | True] 。但这更冗长。)

An example of use of a list comprehension with no qualifier in the literature 1 (pp. 134-136) is the following instance of equational reasoning:在文献1(第 134-136 页)中使用不带限定符的列表推导的示例是以下等式推理示例:

[E | ] ++ L = [E] ++ L = (E:[]) ++ L = E:L

Why did Haskell and Clean programming language designers decide against list comprehensions without qualifiers?为什么 Haskell 和 Clean 编程语言设计者决定反对没有限定符的列表推导? Is there something that would cause bad feature interactions in these languages but not in Miranda?有什么东西会导致这些语言中的不良功能交互,但在 Miranda 中不会?


References:参考:

  1. Simon L. Peyton Jones.西蒙·L·佩顿·琼斯。 The Implementation of Functional Programming Languages . 函数式编程语言的实现 Prentice Hall.普伦蒂斯霍尔。 1987. 1987 年。

  2. The Haskell 98 Report, section 3.11 "List Comprehensions" . Haskell 98 报告,第 3.11 节“列表理解” 1998. 1998 年。

  3. Peter Wentworth.彼得·温特沃斯。 An Introduction to Functional Programming Using Hugs .使用 Hugs 的函数式编程简介 2013. 2013 年。

  4. Rinus Plasmeijer;里纳斯·普拉斯梅耶; Marko van Eekelen;马尔科·范·埃克伦; John van Groningen.约翰范格罗宁根。 Clean Language Report, version 2.2 . 清洁语言报告,2.2 版 2011. 2011 年。

I think the obvious answer is that there is no technical reason to disallow list comprehensions with an empty sequence of qualifiers.我认为显而易见的答案是,没有技术理由禁止使用空的限定符序列进行列表推导。 The requirement is a purely syntactic one.该要求是纯粹的语法要求。 It just so happens that the original Haskell98 report section 3.11 specifies a grammar that requires the list of qualifiers to be non-empty, and the translation rules to turn it into a kernel expression assume this is the case.碰巧的是,最初的 Haskell98 报告第 3.11 节指定了一个语法,该语法要求限定符列表不为空,并且将其转换为 kernel 表达式的翻译规则假设是这种情况。 GHC obeys this grammar, so an expression like [ 10 | ] GHC 遵循这个语法,所以像[ 10 | ] [ 10 | ] is rejected with a parse error. [ 10 | ]因解析错误而被拒绝。

From a technical standpoint, simply relaxing the grammar and adding a single translation rule:从技术的角度来看,简单地放宽语法并添加一个翻译规则:

[ e | ] = [ e | True ]

would address this.会解决这个问题。

In fact, the documentation for the GHC MonadComprehensions extension actually provides a translation for this case:事实上, GHC MonadComprehensions扩展的文档实际上为这种情况提供了翻译:

[ e | ] = return e

and the rest of the translation rules basically assume that cases of the form:而翻译规则的 rest 基本上假设以下形式的情况:

[ e | q, Q ]

apply to the special case:适用于特殊情况:

[ e | q ]

with Q taken to be empty. Q为空。

Once you get past the parser, the rest of GHC handles this special case just fine.一旦通过了解析器,GHC 的 rest 就可以很好地处理这种特殊情况。 In particular, if you use Template Haskell to bypass the parser and construct a comprehension with no qualifiers, you can see that it evaluates as expected.特别是,如果您使用模板 Haskell 绕过解析器并构造一个没有限定符的推导,您可以看到它按预期计算。 (The separate modules here are needed because of the TH phase restricution.) (由于 TH 相位限制,此处需要单独的模块。)

--
-- EmptyComprehension.hs
--

module EmptyComprehension where

import Language.Haskell.TH

-- equivalent to "[ 10 | ]"
x :: ExpQ
x = compE [noBindS (litE (integerL 10))]


--
-- Test.hs
--

{-# LANGUAGE TemplateHaskell #-}

import EmptyComprehension

main = print $(x)  -- will print `[10]`

As for why the language was designed this way, I imagine it was either an oversight or perhaps it was considered at some point but the syntax [10 | ]至于为什么要这样设计语言,我想这要么是疏忽,要么可能是在某个时候考虑过的,但语法[10 | ] [10 | ] was thought to be too bizarre to allow. [10 | ]被认为太奇怪了,不允许。

On a related note, empty case s were also disallowed by the original Haskell98 report but then permitted via an EmptyCase extension when it was discovered that they could actually be useful.在相关的说明中,原始 Haskell98 报告也不允许空case s,但当发现它们实际上有用时,通过EmptyCase扩展允许它们。

I think you might have trouble convincing anyone that a similar extension for comprehensions is worthwhile.我认为你可能很难说服任何人对理解进行类似的扩展是值得的。 In the comments, you mention automatic source generation, but it's easy to handle that case specially or add an extra True qualifier to every comprehensive (or -- if you're generating source via TemplateHaskell -- just bypass the restriction directly).在评论中,您提到了自动源生成,但很容易专门处理这种情况,或者为每个综合添加一个额外的True限定符(或者 - 如果您通过 TemplateHaskell 生成源 - 只需直接绕过限制)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM