【问题标题】:Does an expression exist such that <<expression>> == <<expression>> is always false?是否存在使得 <<expression>> == <<expression>> 始终为假的表达式?
【发布时间】:2021-12-30 11:55:27
【问题描述】:

我不是 Haskell 方面的专家。这个问题并不完全是 Haskell 问题,但我知道 Haskell 的人会更好地理解我想要实现的目标。

所以我正在构建一种动态语言,我希望它是纯粹的……完全纯粹的。 (支持 IO 效果,我已经知道原因,但这不是这个问题的一部分)

另外,我希望它具有某种形式的多态性,所以我正在玩弄添加类支持的想法。

(另外,语言中的所有内容都应该是一个表达式,所以是的,没有语句)

在探索这个想法时,我最终意识到,为了使其具有引用透明性,类表达式也应该能够被替换。

类表达式的主要功能之一是检查某个值是否是它的实例。

所以

val Person =class {...}
val person1 =Person(blabla)

Person.instantiated(person1) // returns true

// Equivalent to

class {...}. 
instantiated(class{...}(blabla))

然而!最后一部分毫无意义……感觉不对,好像我创建了两个不同的类

所以!

有没有这样的表达方式

val expr = <<expression>>
expr == expr // true

但是&lt;&lt;expression&gt;&gt; == &lt;&lt;expression&gt;&gt; 是假的?

使用纯语言?

我觉得我问的是等价于问newtypeHaskell 语句是否可以变成表达式

【问题讨论】:

  • 0/0 == 0/0 是任何支持浮点数的语言的规范示例;因为根据 Haskell 遵循的 IEEE-754 语义,NaN 不等于自身。
  • 这取决于== 的含义。当我阅读“==”时,我希望它具有等价关系的属性。等价关系的基本属性之一是自反性:a == a 对应于基础集合的每个元素 a
  • 您是不是说 两个 不同的表达式 ab 可能评估为相同的
  • “类表达式的主要功能之一是检查某个值是否是它的实例。” 呃! 我的意思是,是的,这在实践中确实发生了很多,但很多人会认为这完全违背了正确的 OO 精神。 - 无论如何,我真的不明白这与问题有何关系......
  • 必须承认这是一个很难问的问题......我很难措辞,就像我正在努力寻找答案一样

标签: class haskell functional-programming expression statements


【解决方案1】:

按照您提出问题的方式,您可能至少会得到一些关于 == 运算符特性的答案(而且,在我写这篇文章时,您已经收到了一条评论影响)。但是,这不是你要问的,所以忘记==。回到你的课堂示例。

参照透明意味着之后:

val Person = class {<PERSONCLASSDEFN>}
val person1 = Person(<PERSONARGS>)

两种表达方式:

Person.instantiated(person1)

和:

(class {<PERSONCLASSDEFN>}).instantiated((class {<PERSONCLASSDEFN>})(<PERSONARGS>))

应该是无法区分的。也就是说,如果一个程序替换另一个程序,程序的含义不应改变,反之亦然。

因此,类的标识必须取决于它们的定义(大括号中的部分),而不是它们被(重新)定义的位置或次数或给定的名称。

作为一个更简单的示例,您还应该考虑以下含义:

val Person = class {<CLASSDEFN>}
val Automobile = class {<CLASSDEFN>}

val person = Person(<ARGS>)
val automobile = Automobile(<ARGS>)

之后,personautomobile 这两个对象应该是无法区分的。

【讨论】:

  • 正是我的想法。因此,按照我想要的方式创建一个类将是一个有效的操作
  • @Buhr... 我提出了两种可能的解决方案,它们可能会破坏语言的“纯度”。 1. 该表达式的标识取决于定义的位置(如源代码中的位置)和 2. 正是您所说的,但是每个类都从编写它的文件中继承了一些额外的标识符。所以它会按照你说的方式工作。但是我将无法在另一个文件中编写相同的类。即使我完全复制它
  • 如果语法是class Person {...},那么名称可以是值的一部分(或者您可以做类似class { name = Person, ... } 之类的事情,无论您的语法如何)。这样,一个对象至少不太可能成为其他人的随机类的成员,而该随机类恰好具有相同的定义。您可以“手动”跟踪类的名称,即使它没有融入语法(例如,通过使用字符串和类的元组),但将其放入语法强制每个人都提供他们的类一个名字。
【解决方案2】:

我很难理解这个问题到底是关于什么的,但也许问题是你在谈论平等,而实际上你的意思是 equivalence relations

作为同一类的实例的两个对象通常不相等,相应地== 将产生False。然而,它们在作为同一类的实例的意义上是等价的。它们是同一个 equivalence class 的成员(数学术语;在 OO 和 Haskell 中“类”一词的用法都源于此)。

您可以将该等价类作为不同的运算符。比如,在 Python 中

def sameclassinstances(a, b):
    return (type(a) is type(b))

根据您的语言语法,当然也可以是自定义中缀运算符,例如

infix 4 ~=.

另一个问题是相等本身可以被解释为值相等(总是在 Haskell 中),或者某种形式的实现相等或引用相等,这在其他语言中相当普遍。但是如果你希望你的语言是纯粹的,你可能应该远离后者,或者给它起一个有说服力的名字,比如 Haskell 的reallyUnsafePtrEquality

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-26
    • 2018-01-06
    • 2020-07-08
    • 2014-07-23
    • 2018-08-29
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    相关资源
    最近更新 更多