【问题标题】:Is True = False? Understanding binding and pattern matching [duplicate]真 = 假吗?了解绑定和模式匹配[重复]
【发布时间】:2018-06-09 03:45:18
【问题描述】:

我们的一个朋友正在教我们用 Haskell 进行函数式编程的基础知识,他开始写我见过的最稀有的东西:

他从不那么令人惊奇但很酷的东西开始:

(x,y) = (10,20)
(z:zs) = 0 : [1..]

并在前奏曲中展示:

prelude> x
10
prelude> z
0
prelude> takeN 3 zs
[1,2,3]

到目前为止,一切都很好......我不知道你可以这样绑定值

(x,y) = (10,20)
(z:zs) = 0 : [1..]
True = False -- HERE

什么!?班上的每个人都想,好吧,出了点问题,但连编译好的代码都没有,然后就运行了:

prelude> x
10
prelude> 4
4
prelude> True
True

(我阅读了What does `let 5 = 10` do? Is it not an assignment operation? 的问题,我在这里没有使用任何 let,在我的示例中,我将代码写入文件并执行它,所以我的问题还没有得到回答,这些答案都没有用对我来说。)

【问题讨论】:

  • 如果您重新提出以前因重复而关闭的问题,请突出显示差异。
  • 到底是什么问题
  • 在我们的例子中,True = False 是一个无可辩驳的模式,并且由于没有任何变量被它限制,所以没有任何东西强制True 模式和值False 之间的匹配。
  • @DamianLattenero 我会在这里回复你的 Meta 问题,以避免 Meta 影响。我认为您的问题具有重复的价值,不应删除。我猜重新开放投票引起了额外的关注,导致删除投票。幸运的是,在这种情况下有一个简单的出路:放弃另一个问题,转而支持这个问题——它本质上是相同的,针对相同的目标关闭,甚至有有用的补充答案。作为奖励,这个问题不能通过正常方式删除,因为我将它用作其他地方的重复目标。
  • @DamianLattenero [2/2] Meta 效应是当帖子获得大量额外选票时,因为它正在 Meta 问题中进行讨论。我怀疑 Meta 人群会发现第二个问题的存在存在问题,可能会导致投票失败和/或讨论脱轨。

标签: haskell binding pattern-matching


【解决方案1】:

wherelet 都使用 lazy 模式引入了定义方程。

在任何模块中,所有顶级定义都在where 下。

module Main where
         -- ^^^^^

x, y :: Int
(x, y) = undefined

main :: IO ()
main = putStrLn "hello!"

上述程序将按预期打印“hello”。与 (x, y) 匹配的模式在严格的情况下会出现差异,但由于它是惰性的,因此不会出现差异——undefined 表达式永远不会被评估。

在 GHCi 中键入的定义也在隐式 let 下。

知道这一点后,问题中提到的问题正是let 5 = 10问题中的问题。

【讨论】:

  • let 5 = 10let True = False 相当没用,但实际上有人可能想写,例如,let Just _ = x,尽管 PartialTypeSignaturesTypeApplications 现在更适合这种情况。跨度>
【解决方案2】:

在 Haskell 中,一个 let “绑定”是做模式匹配。 Haskell 中恰好有两种模式匹配绑定:你可以写P = x,其中P 是一个模式,或者你可以写v1 p1 p2 ... pn = x,其中每个pi 是一个模式。这定义了(部分)函数v1。什么是模式? 模式是一个变量v,它导致v 在匹配成功时绑定到正在匹配的任何内容。或者一个模式可能是一个像 7 这样的常数,当匹配完成时,只有当被匹配的东西等于常数时,它才会成功。或者模式可能是数据类型的变体:如果 Foo 是类型 Bar 的变体(构造函数),采用 n 个参数,则 Foo p1 p2 ... pn,其中 pi 是模式,是一个模式,它着眼于Bar 类型的对象,如果它是 Foo 变体并且每个 pi 成功匹配,则成功匹配。

因为 Haskell 是惰性的,所以强制模式匹配发生的唯一方法是使用一个由模式匹配绑定的变量。因此,可以使用x 强制将x 绑定到let (x,5)=(6,6),这会导致匹配失败。如果变体没有参数,则无法强制匹配,因此匹配不会失败。因此let True = False 会失败,如果你让匹配发生,但因为没有办法让匹配发生,所以没有错误。请注意,您不是重新绑定 True,而是将其用作不带参数的模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多