热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

将文字分配给GHC中的术语

出于好奇,为什么下面的程序1=0"hello"="world"由

出于好奇,为什么下面的程序

1 = 0
"hello" = "world"

由 GHC 有效和编译?这仅仅是一个错误还是一个功能?谢谢!

回答


这是允许的,因为它是语言规则的自然结果,并且没有足够的问题在语言规范中设置特殊情况来阻止它。

自然后果

有两种标准的定义:函数定义和数据定义。在函数定义中,您可以将模式作为参数写入等号左侧的函数。在数据定义中,您可以在等号左侧单独编写模式以匹配等号右侧的数据。所以,这些事情都是允许的:

x = 3
x@y = 3
[x, y, z] = [3, 4, 5]
[x, _, z] = [3, 4, 5]
[x, 4, z] = [3, 4, 5]
x:_ = "xsuffix"
x:"suffix" = "xsuffix"

数字文字和字符串文字是模式。(前一个 desugars 变成一个调用 的守卫(==)。)所以这些也是允许的:

3 = 3
x@3 = 3
[3, 4, 5] = [3, 4, 5]
"xsuffix" = "xsuffix"
-- and yes, these too
3 = 4
"xsuffix" = "lolno"

没有问题

与语言的所有其他部分一样,数据定义是惰性的:它们表示的模式匹配计算在需要之前不会执行(通过检查匹配绑定的变量之一)。由于"hello" = "world"1 = 0不绑定任何变量,它们代表的模式匹配计算——这将抛出异常——永远不会执行。所以避免允许它们并不是非常重要。

...除非它是

但是等等...我们说这是一个有效的模式:

x@3 = 3

而这个类似的发散并绑定一个变量:

x@3 = 4

怎么会一个被允许?这更难回答!我认为尝试考虑一些可以防止这种情况的语言规则是非常合理的。一般而言,合理且完备的规则当然是不可判定的,因为等式的右侧可以进行任意计算。但是您还可以做出其他选择;例如:


  • 不允许在数据定义中使用可反驳的模式。如果模式可能无法匹配,则它是可反驳的。例如,x是无可辩驳,x@y是无可辩驳,_是无可辩驳的,但x:y是可辩驳,True是可辩驳,()是可辩驳的(因为它发散在RHS是底部)。这是迄今为止最简单的,并且会排除x@3 = 4"hello" = "world"两者。不幸的是,它也会排除非常有用的东西,比如[x, y, z] = [3, 4, 5].

  • 实施终止检查器,并要求可反驳模式的 RHS 终止。如果您的分析可以决定某些计算终止——例如,通过发现其中的所有递归都是结构性的或其他东西,则存在终止检查算法的整个家庭手工业——那么您可以让编译器进行检查。如果它确实终止,编译器实际上可以在编译期间运行计算,并仔细检查给定的模式实际上是否与值匹配。这样做的缺点是终止检查算法非常复杂,因此这给编译器编写者带来了很大的负担,并且有些是人类难以预测的,这使得针对它的编程让用户感到沮丧。

  • 要求程序员证明匹配不能失败。您可以为程序员引入一种机制来为他们的程序编写证明,并要求他们证明匹配不会失败。这朝着依赖类型的方向发展;这种转变的两个主要成本通常是程序效率的降低,以及用这种语言编写程序需要更多的努力。

语言设计者做出了许多选择(不仅仅是在模式匹配语义中),这些选择在让程序员和编译器编写者的生活更轻松方​​面是错误的,但允许更多的程序抛出异常或永远不会完成。这是一个这样的地方——数据定义中允许可反驳的模式,即使这会导致崩溃,因为该策略的实现是有用的、简单的和可预测的。



  • @WillNess I have now added a section on why things like `x@1 = 0` are allowed. Thanks!




回答


因为这些文字是模式,所以您正在使用模式绑定。

letHaskell 中的绑定是惰性的,因此不执行实际的模式匹配。

但是如果我们强制匹配,它确实失败了:

> :{
let
x@1 = 0
in
1
:}
1 -- no assignment! NB
it :: Num a => a
> :{
let
x@1 = 0
in
x
:}
*** Exception: :87:1-7: Irrefutable pattern failed for pattern x@1

因为1确实不是 0

因此,这不是 GHC实现的错误或功能,而是 Haskell 语言本身的功能。



  • "let bindings in Haskell are lazy, so no actual pattern matching is performed." is not such explanation? I thought it was.





推荐阅读
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 本文详细介绍了C语言的起源、发展及其标准化过程,涵盖了从早期的BCPL和B语言到现代C语言的演变,并探讨了其在操作系统和跨平台编程中的重要地位。 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • 异常要理解Java异常处理是如何工作的,需要掌握一下三种异常类型:检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常ÿ ... [详细]
  • 本文深入探讨了面向切面编程(AOP)的概念及其在Spring框架中的应用。通过详细解释AOP的核心术语和实现机制,帮助读者理解如何利用AOP提高代码的可维护性和开发效率。 ... [详细]
  • 本题探讨了在一个有向图中,如何根据特定规则将城市划分为若干个区域,使得每个区域内的城市之间能够相互到达,并且划分的区域数量最少。题目提供了时间限制和内存限制,要求在给定的城市和道路信息下,计算出最少需要划分的区域数量。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 利用决策树预测NBA比赛胜负的Python数据挖掘实践
    本文通过使用2013-14赛季NBA赛程与结果数据集以及2013年NBA排名数据,结合《Python数据挖掘入门与实践》一书中的方法,展示如何应用决策树算法进行比赛胜负预测。我们将详细讲解数据预处理、特征工程及模型评估等关键步骤。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 华为智慧屏:超越屏幕尺寸的智能进化
    继全球发布后,华为智慧屏于9月26日在上海正式亮相,推出65英寸和75英寸版本。该产品不仅在屏幕尺寸上有所突破,更在性能和智能化方面实现了显著提升。 ... [详细]
  • 本文详细介绍了8051系列微控制器的中断系统,特别是C51编译器中interrupt和using关键字的作用及其使用方法。通过深入分析这两个关键字的功能,帮助开发者更好地理解和优化中断程序的设计。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 基于结构相似性的HOPC算法:多模态遥感影像配准方法及Matlab实现
    本文介绍了一种基于结构相似性的多模态遥感影像配准方法——HOPC算法,该算法通过相位一致性模型构建几何结构特征描述符,能够有效应对多模态影像间的非线性辐射差异。文章详细阐述了HOPC算法的原理、实验结果及其在多种遥感影像中的应用,并提供了相应的Matlab代码。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
author-avatar
林俊雯868043
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有