Haskell

[TOC]

Haskell

GHCI

  1. 通過Tab可以自動補全
  2. 通過 :browser 模塊名稱,瀏覽該模塊下的函數
  3. :info 函數名 顯示函數相關信息
  4. :set +t 每次輸出都會攜帶輸出類型信息

標準庫函數

map

遍歷數組,針對數組中的元素進行映射轉換處理;映射轉換是有一個函數組成的


-- (\x -> x ^2 ) 表示定義了一個匿名函數(lambda 表達式)
-- 從[1..10] 這個數組中取出每一個元素,傳給匿名函數,x則表示的就是傳入的元素
-- 針對傳入的元素做平方操作后放回到數組中

map (\x -> x ^2 ) [1..10]

-- out: [1,4,9,16,25,36,49,64,81,100]

filter

遍歷數組,針對數組中的元素進行過濾判斷處理;過濾判斷函數必須返回值為Bool類型


filter (\x -> x `mod` 3 == 0 ) [5..25]

-- out : [6,9,12,15,18,21,24]

lambda 表達式

\ 作為開始,并且需要用括號包裹; -> 之前的是參數,多個參數用空格分隔,之后的表示函數體;

關鍵字 fold

針對數組進行左右折疊操作

foldl/foldr scanl/scanr

foldl 左折疊操作 foldr 右折疊操作
scanl 記錄折疊操作狀態,相當于是foldl的執行過程記錄
foldl1 foldr1 相比fold1 少了累計值,其實累計值用的是數組的第一個元素
scanl1 scanr1


-- foldl :: (b -> a -> b)  -> b -> [a] -> b

-- (+) 對應 (b -> a -> b) 表示 加函數 對應 b 和 a兩個參數并且返回 b類型
-- 0  對應  -> b 表示的是累計值
-- [1..10] 對應 -> [a] 表示的是數組
-- 輸出值 對應 -> b

-- 整體過程: 用 0+1的結果作為 累計值,再加 2 ,依次類推

foldl (+)  0 [1..10]

--out: 55

scanl (+)  0 [1..10]

--out: [0,1,3,6,10,15,21,28,36,45,55]

含有$ 的函數

$ 用來斷開整個函數,以使得 $ 的右側先執行,意義在于函數都是從左到右的優先級;
$ 的優先級最低,一定程度上可以減低括號的使用


-- 表示 5 * (2+7)
(*) 5 ((+) 2 7) 
-- 兩者等同,如去掉 $ 則無法正確執行
(*) 5  $ (+) 2 7
-- out: 45

-- 此處表示用$ 可以將數據作為函數調用
map ($ 3) [(4+),(10*),(^2),sqrt]  

-- out : [7.0,30.0,9.0,1.7320508075688772]

Function composition 函數組合

函數組合就是多個函數組合成一個串行的函數鏈,用 點號(.) 進行連接;
組合函數是前一個函數的參數類型需要同后一個函數的回傳值類型一致
fx (fy (fz p)) 使用組合方式為 (fx . fy . fz) p,fz p執行后的返回值類型需要同fy的參數類型一致

不建議使用組合方式,形成復雜的函數鏈條,可以拆分成多個子函數鏈,使用let綁定一個函數名稱,可以提高代碼可讀性


 4 + (3*4)

-- 使用函數的方式編寫 $表示先執行 3 *4 
 (+) 4 $ (*) 3 4

-- 使用點號組合函數,組合函數  
-- +4 和 *3 都是一個不完全函數,相當于是都只傳了一個參數的函數
-- 先將參數 4 傳給 *3 ,然后將結果 12 傳給 +4 ,所以得到16
((+4) . (*3)) 4

 (+4) . (*3) $ 4

let sx = (+4) . (*3) in sx 4

-- out: 16

Module 模塊

模式是含有一組相關的函數、型別和型別類的組合;

-- import 用于在代碼中裝載模塊
-- qualified 顯示代碼中需要引用某函數時需要加上 Data.Map前綴,為了解決加載模塊中函數名沖突的情況
-- as M,則是簡寫 Data.Map前綴 為M
import qualified Data.Map as M;

構建模塊

-- 以hs文件名 構建模塊
module fileName
( functionName1,
  functionName2,
  functionName3
) where

-- 以hs文件所在目錄,構建子模塊
module fileDir.fileName
( functionName1,
  functionName2,
  functionName3
) where

構建Types 和 Typeclasses


data Shape = Circle Float Float Float | Ractangle Float Float Float


Record Syntax

Type parameters 型別參數

類似java 里面的泛型,針對型別不固定的情況,可以用型別參數的方式達到更好的通用性


-- Map 就是攜帶了 k v 兩個型別參數
import qualified Data.Map as Map 

Derived instances

deriving (Eq, Ord, Show, Read, Bounded, Enum)

  • Eq 比較
  • Ord 排序
  • Show 顯示成字符串
  • Read 解析成具體的型別
  • Bounded 邊界
  • Enum 枚舉

Type synonyms

型別同義詞,相當于給型別取了個別名

-- String 就是字符數組的別名
type String = [Char]

Recursive data structures (遞歸地定義數據結構)

在定義型別時,值構造子又使用了定義的型別,形成遞歸

-- 模擬標準庫中的List的遞歸  
data List a = EmptyList | Cons { listHead:: a, listTail :: List a } deriving (Show,Read,Eq,Ord)

IO

工具

  1. 檢索函數
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 工具 haskell platform,直接百度安裝. 打開控制臺輸入ghci即進入交互模式。 假如定義了myfu...
    咣咣當閱讀 11,227評論 4 6
  • 136.泛型 泛型代碼讓你可以寫出靈活,可重用的函數和類型,它們可以使用任何類型,受你定義的需求的約束。你可以寫出...
    無灃閱讀 1,512評論 0 4
  • 在 ghci 里設置一下顯示類型信息: 設置了 +t 后,執行結果后面會跟一行顯示結果的類型,每次退出 ghci ...
    焉知非魚閱讀 1,987評論 0 0
  • 第一章 類型系統和函數 類型 數據類型 Bool Char Int Word Integer Float Doub...
    15d843cd48a8閱讀 1,748評論 0 1
  • 類型系統 強大的類型系統是 Haskell的 一個非常大的優勢。 Haskell 所有表達式類型在編譯時判斷。這樣...
    焉知非魚閱讀 1,798評論 2 3