什么是“等于等于”等于“

时间:2015-05-09 21:36:58

标签: haskell

我是Haskell新手和阅读:

http://www.seas.upenn.edu/~cis194/spring13/lectures/01-intro.html

它声明“在Haskell中,人们总能”等于等于“等于”,就像你在代数课上学到的一样。“这是什么意思,它有什么优势?

我不记得在代数中学习这个,但也许我不认识这个术语。

2 个答案:

答案 0 :(得分:11)

这意味着如果您知道A(表达式)等于B(另一个表达式),那么您可以随时替换A B涉及A的表达式,反之亦然。

例如,我们知道even = not . odd。因此

   filter even
= 
   filter (not . odd)

另一方面,我们知道odd满足以下等式

 odd = (1 ==) . (`mod` 2)

因此,我们也知道

   filter even
 =
   filter (not . odd)
 =
   filter (not . (1 ==) . (`mod` 2))

此外,您知道mod 2始终会返回01。因此,通过案例分析,以下内容是有效的。

   not . (1 ==)
= 
   (0 ==)

因此,我们也可以说

  filter even
= 
  filter ((0 ==) . (`mod` 2))

能够等于等于等于的优点是通过在等式之后按摩等式来设计程序,直到找到合适的定义,就像在典型的求解x 中一​​样代数的问题。

答案 1 :(得分:3)

以最简单的形式,用等于"等于等于"表示用定义替换定义的标识符。例如

let x = f 1 in x + x

可以等效地写为

f 1 + f 1

从某种意义上说,结果是一样的。在GHC中,您可以期望第二个重新计算f 1两次,可能会降低性能,但总和的结果是相同的。

在不纯的语言中,例如Ocaml,上面的两个片段相反,不是等效。这是因为允许副作用:评估f 1可以产生可观察到的影响。例如,f可以定义如下:

(* Ocaml code *)
let f = let r = ref 0 in
        fun x -> r := !r + x ; !r

使用上面的定义,f具有内部可变状态,在每次调用它之前,它会在返回新状态之前通过其参数递增。因此,

f 1 + f 1

将评估为1 + 2,因为状态增加两次,而

let x = f 1 in x + x

将评估为1 + 1,因为只执行一个状态增量。

结果是,在Ocaml中,用其定义替换x将不是保留语义的程序转换。当然,在允许副作用的命令式语言中也是如此。只有在纯语言(Haskell,Agda,Coq,......)中,转换才是安全的。