第九章:type、newtype和惰性求值

夢飛發表於2017-02-27

1.型別別名 type

  • 和data不同,type是一個輕量型的語法,它僅僅是給已經存在的型別提供了一個不一樣的名字,不會定義新的建構函式

  • 在型別檢查時,這個“新”的資料型別和type指代的型別完全等價,編譯器不會區別

  • type型別別名宣告常常用語簡化型別的書寫

    type List a = [a]
    type IntList = [Int]
    
    
    xs = [1,2,3] :: IntList
    
    
    type Shows = String -> String
    --別名標記了字串到字串的函式
    
    
    showsPrec :: Int -> a -> Shows
    -- showsPrec 接收了一個Int 和a型別的引數,返回一個 String -> String型別的函式
    

2.新型別宣告 newtype

newtype允許使用者定義一個只包含一個建構函式,且建構函式只接收一個引數的資料型別,而該型別只在程式碼層面發生表面的打包和解包,在底層允許時,打包和解包的過程會消失。

  • newtype更像是data的一個特例,和type並沒有什麼關係。newtype的寫法和data一樣,但只允許構造一個函式,且建構函式只接收一個引數

  • newtype之所以不用在執行時額外打包和解包,是因為它直接把建構函式接收引數的盒子上的標籤換成了自己定義的新標籤

  • newtype比data的速度更快

  • 底 bottom

    +底在計算機世界中用來表示無法計算的值 | 在Prelude中的undefined就代表這個值

        y= let x = x in x
    

    +我們引入Maybe型別中的Nothing,是用來人為的標記失敗的運算

    +和Nothing的型別是Maybe a型別, | 可以出現在任何種類的計算中,所以|可能是任何型別

    +如果我們在計算的時候沒有開啟裝有 |的盒子,計算是可以繼續下去的

    (||) :: Bool -> Bool -> Bool
    True || _ = True
    _ || True = True
    _ || _ = False
    
    
    True || undefined
    True || let x =x in x
    --均返回True
    
    
    undefined || True
    --程式終止,報錯
    

    +Haskell 中所以的函式行為和||都一樣,

    +不包含|的型別叫做底層型別(unlifted type)否則是上層型別(lifted type)

    +上層型別構起了Haskell最重要的特性——惰性(Lzay)

3.惰性求值

  • 上面例子中函式的行為稱作惰性計算,相對的是**迫切求值**eager evaluation

  • 短路原理:特定的運算子在判斷某些引數之後,可以不用其他引數立即得出結果的行為

  • 兩種函式行為按需傳遞 call-by-need 和按值傳遞 call-by-value

  • 任務盒 thunk :未計算的盒子

  • 標記語義 denotational semantics / 引用透明原則 referential transparency :隨時隨地可以把一個繫結換成它對應的表示式,而不影響程式的求值

    +標記語義的好處:編譯器可以任意替換繫結,或者在不衝突的情況下改變繫結的作用域,實現內聯化簡融合等複雜的變換,而不影響我們書寫的程式的語義

    +後果是你無法預測函式呼叫在什麼時候發生

  • 求值過程 和標記語義相對 +:print :sprint :force 除錯求值過程

    +我們把完全求值後的表示式稱作常態 normal form enter image description here

    +對於類似"hello"和"world"這樣的求值狀態,我們成為弱常態

    +我們引入任務盒、常態和弱常態的概念,實際都是為了解決任務盒堆積的問題

  • seq和deepseq

    +seq強迫計算人物盒

    seq :: a -> b -> b
    ($!) :: (a -> b) -> a -> b
    

    enter image description here

  • $!函式就是$函式的迫切求值版本,嚴格 strict 版本 enter image description here

  • force函式,當對 force x 求值時,x會被求值到常態,這相當於是有副作用版本的id函式

  • GHC的嚴格性分析 strictness analysis

相關文章