【问题标题】:Haskell stripping function of syntactic sugarHaskell 语法糖剥离功能
【发布时间】:2015-08-22 22:58:42
【问题描述】:

我想知道如果没有任何语法糖,下面的函数会是什么样子:

tails1 :: [a] -> [[a]]
tails1 [] = [[]]
tails1 xs@(x:xs') = xs:tails1 xs'

我主要关心@运算符的用法,我已经尝试过下面的方法,但这显然不是正确的方法

tails1 ((:) x ((:) xs' [])) = xs:tails1 xs'

【问题讨论】:

    标签: haskell syntactic-sugar


    【解决方案1】:

    在其他答案中,我们看到了两个建议:

    tailsA (x:xs') = (x:xs'):tailsA xs
    tailsB xs = xs:tailsB (tail xs)
    

    前者具有正确的指称语义,但错误的操作语义。原来的tails只有一次调用(:);因此,人们可能会担心,与tails 的原始定义相比,一个足够愚蠢的编译器在运行tailsA 时会分配额外的cons 单元格。后者也有正确的外延,只有一次调用(:),但插入了一个全新的函数tail,原来没有出现;这种转变似乎需要一些程序员的洞察力才能执行。下面,我将展示如何以不需要程序员洞察力(因此可以由编译器执行)并且不会冒额外分配风险的方式将原始定义转换为没有 at 模式的定义。

    tailsC xs = case xs of
        x:xs' -> xs:tailsC xs'
    

    这里特别有趣:原始等式的右侧逐字显示为 case 语句的右侧。 (tailsAtailsB 都不包含原始方程的右侧作为子项。)这种特殊情况转换建议的 at 模式的一般转换并不完全正确(因为 xs 匹配任何值而xs@(x:xs') 仅匹配非空列表);将 Haskell 风格的模式转换为 GHC 核心风格的案例语句(只检查一个变量,并且其模式都只包含一个构造函数)的完整处理超出了 StackOverflow 答案的范围。有几篇研究论文讨论了如何正确、高效地执行此操作并生成快速代码;另请参阅相关问题 Algorithm for type checking ML-like pattern matching? 以及 Google Scholar 搜索 compiling pattern matching 中的所有结果。

    但基本思想是name@patternpattern 匹配时完全匹配(将所有相同的名称pattern 绑定到所有相同的值),但另外将name 绑定到完整值。

    【讨论】:

    • 您能否提供一般转换的参考(包括正确的模式匹配)?
    【解决方案2】:

    首先您需要了解列表数据类型。 以下是列表数据构造函数:

    [] :: [a]
    (:) :: a -> [a] -> [a]
    

    地点:

    1. [] 创建一个空列表
    2. (:) 接受 aa 列表并返回添加了新元素的 a 列表

    假设您有一个列表[1,2,3,4]。 这可以写成(:) 1 ((:) 2 ((:) 3 ((:) 4 []))) 在表达式 x:xs'x 中,1xs' 将保持 (:) 2 ((:) 3 ((:) 4 []))。 换句话说,: 接受一个元素和一个列表,将这个元素附加到列表中。

    您的示例的等效表达式是:

    tails1 ((:) x xs') = ((:)x xs'):tails1 xs'
    

    x 保存列表的第一个元素,xs' 保存列表的其余部分。 xs' 不能容纳多个元素。在您的示例tails1 ((:) x ((:) xs' [])) = xs:tails1 xs' 中,xs' 应该包含除第一个元素和[] 之外的所有内容。 (在我的例子中,它应该是 2:3:4,这不是一个有效的列表,因为它没有以 [] 结尾)。

    【讨论】:

      【解决方案3】:

      因为tails1 [] 条目首先出现,所以我们不需要确保去糖的tails1 xs@(x:xs') 只匹配非空列表,因为它们保证是非空的。因此,编写xs@(x:xs') 的唯一效果是让我们可以同时访问xstail xs,因此该行可以重写为:

      tails1 xs = xs : tails1 (tail xs)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-24
        • 2020-07-24
        • 1970-01-01
        • 2011-02-19
        • 1970-01-01
        • 2017-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多