我是Haskell新手和阅读:
http://www.seas.upenn.edu/~cis194/spring13/lectures/01-intro.html
它声明“在Haskell中,人们总能”等于等于“等于”,就像你在代数课上学到的一样。“这是什么意思,它有什么优势?
我不记得在代数中学习这个,但也许我不认识这个术语。
答案 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
始终会返回0
或1
。因此,通过案例分析,以下内容是有效的。
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,......)中,转换才是安全的。