最近在学 Haskell ,东西比较零碎,所以把代码片段记下来吧。看的是《Haskell 趣学指南》 (Learn You a Haskell for Great Good)

  • 函数结合优先级最高
  • 一些常用的函数及其用法
  • minmax 只接受两个参数
  • maximumminimum 接受列表
  • ++ 用于拼接列表,复杂度为左侧字符串长度
  • : 用于将一个元素从左侧拼入列表
  • 列表可以根据字典序比较
  • take 数量超过整个列表则会返回整个列表
  • drop 数量超过整个列表则会返回空列表
  • [1..] 支持无限列表
  • [5,4..] 支持指定步长
succ 9 + max 5 4 + 1            -- 16
pred 8                          -- 7
succ 8                          -- 9
min 9 10                        -- 9
max 9.1 9.9                     -- 9.9
[1,2,3,4] ++ [9,10,11,12]       -- [1,2,3,4,9,10,11,12]
'A':" small cat"                -- "A small cat"
[1,2,3,4] > [1,2,3]             -- True
head [1,2,3,4,5]                -- 1
tail [1,2,3,4,5]                -- [2,3,4,5]
last [1,2,3,4,5]                -- 5
init [1,2,3,4,5]                -- [1,2,3,4]
length [1,2,3,4,5]              -- 5
null []                         -- True
reverse [1,2,3,4,5]             -- [5,4,3,2,1]
take 3 [1,2,3,4,5]              -- [1,2,3]
take 10 [1,2,3,4,5]             -- [1,2,3,4,5]
drop 3 [1,2,3,4,5]              -- [4,5]
drop 10 [1,2,3,4,5]             -- []
maximum [1,2,3,4,5]             -- 5
minimum [1,2,3,4,5]             -- 1
sum [1,2,3,4,5]                 -- 15
product [1,2,3,4,5]             -- 120
4 `elem` [1,2,3,4,5]            -- True
[1..5]                          -- [1,2,3,4,5]
[5,4..1]                        -- [5,4,3,2,1]
take 5 [3,6..]                  -- [3,6,9,12,15]
take 10 (cycle [1,2,3])         -- [1,2,3,1,2,3,1,2,3,1]
take 10 (repeat 5)              -- [5,5,5,5,5,5,5,5,5,5]
replicate 10 5                  -- [5,5,5,5,5,5,5,5,5,5]
[0.1, 0.3 .. 1]                 -- [0.1,0.3,0.5,0.7,0.899999,1.099999]
[ x*2 | x <- [1..10]]           -- [2,4,6,8,10,12,14,16,18,20]
[ x | x <- [1..10], x /= 3, x /= 7, x /= 9] -- [1,2,4,5,6,8,10]
[ x+y | x <- [1,2,3], y <- [10,20,30]]      -- [11,21,31,12,22,32,13,23,33]
[(1,0,0), (0,1,0), (0,0,1)]
fst (1,2)                       -- 1
snd (1,2)                       -- 2
zip [1..] ["one", "two", "three", "four", "five"]
              -- [(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
  • 一些函数
  • 类型
  • 模式匹配
  • 递归函数设计
  • guard 防止大坨 if-else
  • wherelet ... in ...
  • case 模式匹配
length' xs = sum [1 | _ <- xs]

:t [(1,0,0), (0,1,0), (0,0,1)]
:t zip
5 `compare` 3
show [(1,0,0), (0,1,0), (0,0,1)]
read "[1,2,3,4]" ++ [5]
read "[1,2,3,4]" :: [Int]

sayMe :: Int -> String
sayMe 1 = "One!"
sayMe 2 = "Two!"
sayMe 3 = "Three!"
sayMe x = "Not between 1 and 3"

factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n-1)


addVectors :: (Double, Double) -> (Double, Double) -> (Double, Double)
addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

head' :: [a] -> a
head' [] = error "Can't call head' on an empty list."
head' (x:_) = x

firstletter :: String -> String
firstletter "" = "Empty String."
firstletter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]

bmiTell :: Double -> String
bmiTell weight height
    | bmi <= skinny = "You're underweight."
    | bmi <= normal = "You're supposedly normal."
    | bmi <= fat    = "You're fat."
    | otherwise     = "You're a whale."
    where bmi = weight / height^2
          skinny = 18.5
          normal = 25.0
          fat = 30.0

calcBmis :: [(Double, Double)] -> [Double]
calcBmis xs = [bmi w h | (w, h) <- xs]
    where bmi weight height = weight / height^2

(let (a, b, c) = (1, 2, 3) in a+b+c) * 100

calcBmis' :: [(Double, Double)] -> [Double]
calcBmis' xs = [bmi | (w, h) <- xs, let bmi = w / h^2, bmi > 25.0]

describeList :: [a] -> String
describeList ls = "The list is " ++ case ls of []  -> "empty."
                                               [x] -> "a singleton list."
                                               xs  -> "a longer list."

take' :: (Num i, Ord i) => i -> [a] -> [a]
take' n _
    | n <= 0   = []
take' _ []     = []
take' n (x:xs) = x : take' (n-1) xs

reverse' :: [a] -> [a]
reverse' [] = []
reverse' (x:xs) = reverse' xs ++ [x]

repeat' :: a -> [a]
repeat' x = x : repeat' x

zip' :: [a] -> [b] -> [(a, b)]
zip' _ [] = []
zip' [] _ = []
zip' (x:xs) (y:ys) = (x,y):zip' xs ys

quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
    let smallerOrEqual = [a | a <- xs, a <= x]
        larger         = [a | a <- xs, a > x]
    in quicksort smallerOrEqual ++ [x] ++ quicksort larger