筆記:Haskell函數語言程式設計入門 - 惰性求值簡介
λ演算簡介
定義:Expression -> Constant | Variable | Expression Expression | λ Variable. Expression
α替換:λx.λy.x + y ≡ λa.λy.a + y (不出現命名衝突的情況下的重新命名)
β化簡:(λx.M) N -> [x / N] M (應用時“實參”到“形參”的替換過程)
η化簡:(λx.M) x -> M (似乎只是文字意義上的一種簡化)
⊥(Bottom)
⊥用於表示計算沒有結果(沒有β-nf)的表示式的語義,下面用Haskell中的unedfined作為一個⊥的例項。
每一個ADT都有一個額外的值:“⊥”,但newtype型別不會追加“⊥”
例:
有型別定義:
newtype N = N Int
data D = D Int
函式定義:
n (N i) = 42
d (D i) = 42
有如下應用:
n undefined
d undefined
結果為
42
undefined
可以認為newtype定義的型別(N)和它的第一個值構造子所容納的型別(Int)的是同構的,newtype不追加“⊥”的原因也是為了這種同構,但是一個接受N型別的函式也可能有“⊥”作為輸入,這時參考根據上面同構的想法,可以很自然的理解newtype會把“⊥”“轉嫁”給自己包裹的型別,於是undefined被“轉嫁”給i,而i不必被求值,於是第一個函式返回42。 (對newtype的解釋主要來自這裡)
而d因為模式匹配要對傳入引數進行計算,即使i的值無所謂,但還是要計算D值構造子,於是會對undefined進行計算,結果就undefined了。
當函式引數為⊥時,如果函式結果為⊥(⊥在語法上是有型別的,但在語義上我們不區分),稱函式嚴格,否則非嚴格。E.g. n是非嚴格的,d是嚴格的。
d (D undefined) --undefined為Int型別的一個值,故函式返回42(沒有對D值構造子計算內容)。
d' (D !i) = 42 --如果想要求值構造子的引數,型別前加“!”。
seq 以及 $!
seq : : a -> b -> b --會直接返回第二個引數,但會對第一個引數嚴格計算。
($!) :: (a -> b) -> a -> b --同($)但會嚴格計算第二個引數。
表示式形態和thunk
WHNF:
形如F M1 M2 M3 的表示式
- F為常量(值,內建函式,值構造子)
F為λ表示式,但後跟M1到Mn不能使其完全應用而導致不能化簡。
- 表示式可以寫成樹狀結構,此處的F為頂層,由於它引數不夠,內部子樹不必計算。
- 總結為表示式樹的頂層無法化簡時,表示式為WHNF。
HNF:為WHNF真子集
形如λx1.λx2. ... λxn.(v M1 M2 ... Mm)
- (v M1 M2 ... Mm) :同WHNF1.
- 當λ部分退化時,即為(v M1 M2 ... Mm).
- 否則, 要求完全β化簡,即不允許WHNF中的外圍(F後的)M1到Mn,並且F的引數巢狀層同樣要求如此
- λx.(λy.y + x) 3 :此處(λy.y + x) 3可以繼續化簡。不為HNF。
- λx.x ((λy.y) 5) :此處處於λ的內部表示式(v M1 M2 ... Mm),不作要求,為HNF。
NF:為HNF的真子集
- 表示式的任意部分都完全化簡。
- 相對於上面兩個,主要是(v M1 ... Mn)部分,NF要求Mx本身是最簡的。
沒搞清的地方
內建函式何時求值?
- 以上三者都是定義在lambda操作上的化簡,內建函式何時求值? 作者說seq會將表示式求值到HNF,(+) 1 1 應為HNF(甚至NF),但是seq會將其求值為2。
相關文章
- Python函數語言程式設計系列007:惰性求值Python函數程式設計
- 函數語言程式設計簡介函數程式設計
- 函數語言程式設計入門函數程式設計
- Haskell學習-函數語言程式設計初探Haskell函數程式設計
- 函數語言程式設計入門教程函數程式設計
- javascript函數語言程式設計簡單介紹JavaScript函數程式設計
- 程式設計正規化 —— 函數語言程式設計入門程式設計函數
- 函數語言程式設計入門實踐(一)函數程式設計
- JavaScript函數語言程式設計入門經典JavaScript函數程式設計
- JavaScript函數語言程式設計無痛入門JavaScript函數程式設計
- Python函數語言程式設計入門教程Python函數程式設計
- 函數語言程式設計學習-SICP-LISP-流STREAM的實現-流程式設計思路和惰性/延時求值2函數程式設計Lisp
- JavaScript 函數語言程式設計介紹JavaScript函數程式設計
- 物件-函數語言程式設計簡史物件函數程式設計
- 函數語言程式設計入門實踐 —— Compose/Pipe函數程式設計
- Haskell 入門筆記(四)Haskell筆記
- [scala]函數語言程式設計思想入門函數程式設計
- 函數語言程式設計函數程式設計
- Lambda表示式入門--函數語言程式設計與函式式介面函數程式設計函式
- Scala 函數語言程式設計(一) 什麼是函數語言程式設計?函數程式設計
- java8函數語言程式設計筆記-科裡化Java函數程式設計筆記
- java8函數語言程式設計筆記-延遲性Java函數程式設計筆記
- 【廖雪峰python進階筆記】函數語言程式設計Python筆記函數程式設計
- 函數語言程式設計實用介紹(下)函數程式設計
- 函數語言程式設計實用介紹(上)函數程式設計
- Python函數語言程式設計:從入門到走火入魔Python函數程式設計
- Python的函數語言程式設計,從入門到⎡放棄⎦Python函數程式設計
- 函數語言程式設計讓你忘記設計模式函數程式設計設計模式
- Go語言併發程式設計簡單入門Go程式設計
- 函數語言程式設計,真香函數程式設計
- Java 函數語言程式設計Java函數程式設計
- javascript函數語言程式設計JavaScript函數程式設計
- 初探函數語言程式設計函數程式設計
- 函數語言程式設計初探函數程式設計
- JavaScript 函數語言程式設計JavaScript函數程式設計
- 《Java8函數語言程式設計》讀書筆記---類庫Java函數程式設計筆記
- RxJava2.x 學習筆記(一)函數語言程式設計RxJava筆記函數程式設計
- 函數語言程式設計-記憶化快取函數程式設計快取