关于“让5 = 10”

如果我说let 5 = 10 ,为什么5 + 1返回6而不是11

当你说

 let 5 = 10 

这不是对5的重新定义,而是一种模式匹配,当你说的时候会发生同样的情况

 foo 5 = undefined ... foo 10 ... 

如果匹配,模式就会失败。

在letexpression式中,匹配是懒惰的。 这意味着匹配只在被它所绑定的variables进行评估时完成。 这使我们能够写出类似的东西

  let foo = undefined in 10 

在你的expression式中,没有variables被绑定,所以模式永远不会匹配。

可以说这样没有variables的模式在绑定中是没有意义的,应该由编译器来检测,但是这种语言并不禁止它们。

基本上,

 let 5 = 10 in ... 

相当于

 case 10 of ~5 -> ... 

请注意~ ,这标志着一个懒惰 ,或无可争辩的模式 。 这是一个匹配所有事物的模式,并将匹配推迟到实际需要某个variables的点。 模式5中没有variables,所以什么都没有发生。

这个angular落案例是无用的,可以说编译器应该在这里发出警告。

为了澄清懒惰模式的含义,请考虑这一点:

 case f 3 of (x,y) -> g 10 xy 

这里f 3首先被评估(对WHNF),暴露了对构造函数。 然后, x,y绑定到(尚未评估的)对组件。 最后,计算g 10 ,结果应用于x (现在可能需要),然后应用于y (这可能导致xy被要求)。

通过对比,

 case f 3 of ~(x,y) -> g 10 xy 

不是从评估f 3开始的。 相反, x被绑定到未评估的fst (f 3)y被绑定到未被评估的snd (f 3) 。 我们从评估g 10开始。 然后,我们将它应用于x :这可能导致x被要求,引发f 3的评估。 然后,我们将结果应用于y ,导致类似的评估。 大多数实现将实际上共享 xy之间的f 3的结果,以便最多计算一次。

正如@nm所说,你是模式匹配。 这里有些例子。

模式匹配可以成功

 Prelude> let (a, 10) = (15, 10) in a 15 

或失败。

 Prelude> let (a, 10) = (15, 15) in a *** Exception: <interactive>:5:5-22: Irrefutable pattern failed for pattern (a, 10) 

由于Haskell是懒惰的,如果你不使用结果值,你的代码将会成功。 这基本上是你在做什么:

 Prelude> let (a, 10) = (15, 15) in "Something else" "Something else" 

请注意,types仍然需要检查:

 Prelude> let (a, 10, 999) = (15, 15) in "Something else" <interactive>:7:20: error: • Couldn't match expected type '(t, Integer, Integer)' with actual type '(Integer, Integer)' • In the expression: (15, 15) In a pattern binding: (a, 10, 999) = (15, 15) In the expression: let (a, 10, 999) = (15, 15) in "Something else" • Relevant bindings include a :: t (bound at <interactive>:7:6)