簡體   English   中英

具有零限定符的列表推導(ZF 表達式)

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

列表推導式(或 ZF 表達式)包括一系列限定符,它們可以是生成器布爾值表達式(“過濾器表達式”),充當警衛。

沒有限定符的列表推導式——例如, [1 | ] [1 | ] – 在 Miranda 1 (p. 130)中(顯然)有效,但在 Haskell 2、3 第 42 頁)中無效 – 我在ghci解釋器中嘗試過 – 並且(顯然)在 Clean 4中無效。

(當然,我們可以通過添加一個True保護來模擬它,例如[1 | True] 。但這更冗長。)

在文獻1(第 134-136 頁)中使用不帶限定符的列表推導的示例是以下等式推理示例:

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

為什么 Haskell 和 Clean 編程語言設計者決定反對沒有限定符的列表推導? 有什么東西會導致這些語言中的不良功能交互,但在 Miranda 中不會?


參考:

  1. 西蒙·L·佩頓·瓊斯。 函數式編程語言的實現 普倫蒂斯霍爾。 1987 年。

  2. Haskell 98 報告,第 3.11 節“列表理解” 1998 年。

  3. 彼得·溫特沃斯。 使用 Hugs 的函數式編程簡介 2013 年。

  4. 里納斯·普拉斯梅耶; 馬爾科·范·埃克倫; 約翰范格羅寧根。 清潔語言報告,2.2 版 2011 年。

我認為顯而易見的答案是,沒有技術理由禁止使用空的限定符序列進行列表推導。 該要求是純粹的語法要求。 碰巧的是,最初的 Haskell98 報告第 3.11 節指定了一個語法,該語法要求限定符列表不為空,並且將其轉換為 kernel 表達式的翻譯規則假設是這種情況。 GHC 遵循這個語法,所以像[ 10 | ] [ 10 | ]因解析錯誤而被拒絕。

從技術的角度來看,簡單地放寬語法並添加一個翻譯規則:

[ e | ] = [ e | True ]

會解決這個問題。

事實上, GHC MonadComprehensions擴展的文檔實際上為這種情況提供了翻譯:

[ e | ] = return e

而翻譯規則的 rest 基本上假設以下形式的情況:

[ e | q, Q ]

適用於特殊情況:

[ e | q ]

Q為空。

一旦通過了解析器,GHC 的 rest 就可以很好地處理這種特殊情況。 特別是,如果您使用模板 Haskell 繞過解析器並構造一個沒有限定符的推導,您可以看到它按預期計算。 (由於 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]`

至於為什么要這樣設計語言,我想這要么是疏忽,要么可能是在某個時候考慮過的,但語法[10 | ] [10 | ]被認為太奇怪了,不允許。

在相關的說明中,原始 Haskell98 報告也不允許空case s,但當發現它們實際上有用時,通過EmptyCase擴展允許它們。

我認為你可能很難說服任何人對理解進行類似的擴展是值得的。 在評論中,您提到了自動源生成,但很容易專門處理這種情況,或者為每個綜合添加一個額外的True限定符(或者 - 如果您通過 TemplateHaskell 生成源 - 只需直接繞過限制)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM