【问题标题】:Reassignment in ghcighci中的重新分配
【发布时间】:2020-04-13 22:51:07
【问题描述】:

是否可以在 ghci 中重新分配相同的变量?当然,这在普通的 Haskell 中是不可能的(至少没有像 IORef 这样的东西),但我很好奇,因为 ghci 中的 it 变量是通过启用 :m 选项获得的。启用此功能后,我获得了 it 可以通过 not 将下一个表达式绑定到任何东西来有效地重新分配的体验,例如

λ> 1 + 1
2
it :: Num a => a
λ> it
2
it :: Num a => a
λ> it + 1
3
it :: Num a => a
λ> it
3
it :: Num a => a

有没有办法为任意命名变量实现相同的效果,而不仅仅是特殊的it

【问题讨论】:

  • 不,它不是重新分配,您只需定义一个 second 更多本地范围的变量it
  • 在 ghci 下,x <- return (x+1) 表达式似乎符合您的预期。
  • @jpmarinier 但只有 似乎。 :) 它仍然是阴影,只是在一行代码而不是两行代码中,如所见,例如这里:how to increment a variable in functional programming.

标签: haskell ghci


【解决方案1】:

GHCi 中的每个新行都进入新的嵌套范围。考虑

> x = 1
> x
1
> foo y = x + y
> foo 41
42
> x = 7                 -- new x
> x
7
> bar y = x + y         -- refers to new x
> bar 41
48
> foo 41                -- still refers to the same old x binding
42

x 的第二个绑定定义了 new 同名变量。

自然,它隐藏该名称的先前绑定,使其本身无法访问。不过,之前引用过它的任何其他实体(如 foo)将继续持有 that 引用,无论 newer 嵌套环境的阴影如何。

这遵循 Haskell 中值不变性的原则:foo 保持不变。

一个警告:

> :{
  x = 1
  foo y = x + y
  x = 7                   -- error: conflicting definition
  bar y = x + y
  :}

导致错误,因为在多行模式下输入的行属于同一范围。

换句话说,您的问题的答案是,它会破坏 Haskell 的基本纯度属性。

it 也没有重新分配,它在每个新的嵌套环境中重新定义,只要有任何输出,就绑定到输出值:

> x
7
> it
7
> it_2                       -- made a typo

error: Not in scope: `it_2'
> it+2                       -- no previous output, same `it` in effect
9
> it+2                       -- most recent `it` is 9
11

因此,您始终可以隐藏您的变量并创建一个具有相同名称的新绑定,但您不能更改旧绑定,因为它现在已成为历史的一部分,而过去可以根据定义,不能改变。它已经发生了

或者您可以创建自己的 Haskell 解释器,让用户能够“更改”旧绑定,但真正发生的情况是即使“播放”也会生成解释器的新副本" 从那时起,所有在提示符下记录的用户操作——新定义和所有操作。然后用户最终会得到一个更改的副本,这将忘记第一个副本的存在。那时你甚至可以杀死原版。这是否可以认为是用户改变了过去? 用户的过去没有改变,他们的时间还在继续。就而言,新副本的过去始终是现在的样子。旧的原件(副本?)不见了……一个需要思考的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 2011-02-13
    • 2021-05-13
    相关资源
    最近更新 更多