Haskell
纯函数式
惰性处理
强类型静态类型
不会产生副作用,可以返回一个副作用并被延迟执行
安装使用 stack,然后换成清华源,IDE 用 VSCode + HIE
10.1 + 0.22-- 0.3000000000000000434 * (2.0 + 1)4-- 125"hello" ++ " world"6-- "hello world"7['a', 'b']8-- "ab"9if 5 == 5 then "true" else "false"10-- "true"11if (1) then "true" else "false"12-- error 强类型13"one" + 114-- error1516:set +t -- 打开 t 查看类型17418-- 419-- it :: Num p => p20:t 4 -- :t 查看类型21-- it :: Num p => p
函数
1module Throwaway where23double x = x * 2 -- 自动类型推断 double :: Num a => a -> a4-- a 是一个类型变量,通过传入参数推断出类型 a,之后返回也是 a 类型
1module Throwaway where23double :: Integer -> Integer4double x = x * 2 -- double 2.0 -- error
递归
1let fact x = if x == 0 then 1 else fact (x - 1) * x -- fact :: (Eq p, Num p) => p -> p
模式匹配
1factorial :: Integer -> Integer2factorial 0 = 13factorial x = x * factorial (x - 1)
哨兵表达式
1factorial :: Integer -> Integer2factorial x3 | x > 1 = x * factorial (x - 1)4 | otherwise = 1
元组
1fibTuple :: (Integer, Integer, Integer) -> (Integer, Integer, Integer)2fibTuple (x, y, 0) = (x, y, 0)3fibTuple (x, y, index) = fibTuple (y, x + y, index - 1)45fibResult :: (Integer, Integer, Integer) -> Integer6fibResult (x, y, z) = x78fib :: Integer -> Integer9fib x = fibResult (fibTuple (0, 1, x))
元组和组合
1let second list = head (tail list) -- let 是局部定义2let second = head . tail -- compose 简写
1fibNextPair :: (Integer, Integer) -> (Integer, Integer)2fibNextPair (x, y) = (y, x + y)34fibNthPair :: Integer -> (Integer, Integer)5fibNthPair 1 = (1, 1)6fibNthPair n = fibNextPair (fibNthPair (n - 1))78fib :: Integer -> Integer9fib = fst . fibNthPair -- fib n = fst (fibNthPair n)
1let h:t = [1, 2, 3, 4] -- h = 1, t = [2, 3, 4]23size [] = 04size (h:t) = 1 + size t5-- size "hello world" -> 1167prod [] = 18prod (h:t) = h * prod t910-- zip ['a', 'c'] ['b', 'd'] -> [('a', 'b'), ('c', 'd')]
生成列表
11:[2, 3] -- [1, 2, 3]2[1]:[2, 3] -- error3[1]:[[2], [3, 4]] -- [[1], [2], [3, 4]]45allEven :: [Integer] -> [Integer]6allEven [] = []7allEven (h:t) = if even h then h:allEven t else allEven t8-- allEven [1, 2, 3] -> [2]
1[1 .. 2] -- [1, 2]2[1 .. 4] -- [1, 2, 3, 4]3[10, 4] -- []4[10, 9.5 .. 4] -- [10.0, 9.5, 9.0, 8.5, 8.0, 7.5, 7.0, 6.5, 6.0, 5.5, 5.0, 4.5, 4.0]56take 5 [1 .. ] -- [1, 2, 3, 4, 5]7take 5 [0, 3 .. ] -- [0, 3, 6, 9, 12]
1[x * 2 | x <- [1, 2, 3]] -- [2, 4, 6]2[(y, x) | (x, y) <- [(1, 2), (2, 3)]] -- [(2, 1), (3, 2)]34let crew = ["Lj", "Hgk"]5[(a, b) | a <- crew, b <- crew, a /= b]6-- [("Lj","Hgk"),("Hgk","Lj")]
高阶函数
1module Throwaway where2 squareAll list = map square list3 where square x = x * x4-- squareAll [1, 2, 3] -> [1, 4, 9]56map (\x -> x * x) [1, 2, 3]7-- [1, 4, 9]89map (+ 1) [1, 2, 3] -- (+ 1) 是偏函数10-- [2, 3, 4]1112filter odd [1, 2, 3, 4, 5]13-- [1, 3, 5]1415-- foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b16foldl (\cur acc -> acc + cur) 0 [1 .. 10] -- fold left17-- 551819-- foldl1 :: Foldable t => (a -> a -> a) -> t a -> a20foldl1 (+) [1 .. 10]21-- 55
柯里化
1let prod x y = x * y2let double = prod 23let triple = prod 3
惰性求值
1myRange start step = start:(myRange (start + step) step)2myRange 1 1 -- [1, 2, 3, ............]3take 5 (myRange 10 2) -- [10, 12, 14, 16, 18]
1lazyFib x y = x:(lazyFib y (x + y))2fib = lazyFib 1 13fibNth n = head (drop (n - 1) (take (n) fib))45take 5 (lazyFib 1 1) -- [1, 1, 2, 3, 5]6take 5 fib -- [1, 1, 2, 3, 5]7take 5 (drop 200 fib) -- [453973694165307953197296969697410619233826, 734544867157818093234908902110449296423351, 1188518561323126046432205871807859915657177, 1923063428480944139667114773918309212080528, 3111581989804070186099320645726169127737705]8fibNth 9 -- 349take 5 (zipWith (+) fib (drop 1 fib)) -- [2, 3, 5, 8, 13]10take 5 (map (*2) [1 ..]) -- [2, 4, 6, 8, 10]11take 5 (map ((* 2) . (* 5)) fib) -- [10, 10, 20, 30, 50]
类型
1'a' -- it :: Char2"abc" -- it :: [Char]3"abc" == ['a', 'b', 'c']4-- True5-- it :: Bool
PlayCard.hs
1module PlayCard where23-- 自定义类型4data Suit = Spades | Hearts deriving (Show) -- 继承 Show 函数5data Rank = Ten | Jack | Queen | King | Ace deriving (Show)6type Card = (Rank, Suit)7type Hand = [Card]89value :: Rank -> Integer10value Ten = 111value Jack = 212value Queen = 313value King = 414value Ace = 51516cardValue :: Card -> Integer17cardValue (rank, suit) = value rank
1-- 范型2backwards :: [a] -> [a] -- 不止是 Hand -> Hand3backwards [] = []4backwards (h:t) = backwards t ++ [h]
1data Triplet a = Trio a a a deriving (Show)2:t Trio 'a' 'b' 'c' -- it :: Triplet Char
1-- 递归类型2data Tree a = Children [Tree a] | Leaf a deriving (Show)3depth (Leaf _) = 14depth (Children c) = 1 + maximum (map depth c)56let tree = Children [Leaf 1, Children [Leaf 2, Leaf 3]]7-- Children [Leaf 1, Children [Leaf 2, Leaf 3]]8-- it :: Num a => Tree a910-- 模式匹配11let (Children ch) = tree12-- ch -> [Leaf 1,Children [Leaf 2,Leaf 3]]1314depth tree -- 3
1class Eq a where2 (==), (/=) :: a -> a -> Bool3 -- 最小完整定义4 -- (==) 或 (/=)5 x /= y = not (x == y)6 x == y = not (x /= y)78-- hs 中 Eq 类的定义
🤩 monad
处理 I / O
1tryIo = do putStr "Enter your name: " ;2 line <- getLine ;3 let { backwards = reverse line } ;4 return ("Hello. Your name backwards is " ++ backwards)
Maybe
1case (html doc) of2 Nothing -> Nothing3 Just x -> case body x of4 Nothing -> Nothing5 Just y -> paragraph 2 y
feeling
类型系统
纯