热门标签 | 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.





推荐阅读
  • protobuf 使用心得:解析与编码陷阱
    本文记录了一次在广告系统中使用protobuf进行数据交换时遇到的问题及其解决过程。通过这次经历,我们将探讨protobuf的特性和编码机制,帮助开发者避免类似的陷阱。 ... [详细]
  • 本文提供了一种有效的方法来解决当Android Studio因电脑意外重启而导致的所有import语句出现错误的问题。通过清除缓存和重建项目结构,可以快速恢复开发环境。 ... [详细]
  • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
  • 本文探讨了如何在 Spring MVC 框架下,通过自定义注解和拦截器机制来实现细粒度的权限管理功能。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • Java实现:从键盘输入系数求解一元二次方程
    本教程详细介绍了如何使用Java编程语言,通过键盘输入系数a、b、c来求解一元二次方程ax² + bx + c = 0的根。 ... [详细]
  • 深入探讨前端代码优化策略
    本文深入讨论了前端开发中代码优化的关键技术,包括JavaScript、HTML和CSS的优化方法,旨在提升网页加载速度和用户体验。 ... [详细]
  • 本文探讨了Python类型注解使用率低下的原因,主要归结于历史背景和投资回报率(ROI)的考量。文章不仅分析了类型注解的实际效用,还回顾了Python类型注解的发展历程。 ... [详细]
  • OpenCV中的霍夫圆检测技术解析
    本文详细介绍了如何使用OpenCV库中的HoughCircles函数实现霍夫圆检测,并提供了具体的代码示例及参数解释。 ... [详细]
  • 深入解析C语言中的关键字及其分类
    本文将全面介绍C语言中的关键字,并按照功能将其分为数据类型关键字、控制结构关键字、存储类别关键字和其他关键字四大类,旨在帮助读者更好地理解和运用这些基本元素。C语言中共有32个关键字。 ... [详细]
  • 本文详细介绍了如何在Spring框架中设置事件发布器、定义事件监听器及响应事件的具体步骤。通过实现ApplicationEventPublisherAware接口来创建事件发布器,利用ApplicationEvent类定义自定义事件,并通过ApplicationListener接口来处理这些事件。 ... [详细]
  • TCP协议中的可靠传输机制分析
    本文深入探讨了TCP协议如何通过滑动窗口和超时重传来确保数据传输的可靠性,同时介绍了流量控制和拥塞控制的基本原理及其在实际网络通信中的应用。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
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社区 版权所有