series

  • Basic grammar for notes in the Haskell Guide to Fun Learning
  • Notes in the Haskell Guide to Fun Learning
  • Function of notes in the Haskell Guide to Fun Learning
  • Haskell’s Guide to Fun Learning notes of higher order functions
  • Module of notes in the Haskell Guide to Fun Learning
  • Custom types of notes in the Haskell Guide to Fun Learning
  • I/O notes from the Haskell Guide to Fun Learning

Pattern matching

Write the pattern and Haskell will match it for you directly. Such as:

lucky: :Int -> String
lucky 7 = "7 is the lucky number!"
lucky x = "sorry, you are not lucky"
Copy the code

Run after loading

Lambda > lucky2
"sorry, you are not lucky"Lambda > lucky3
"sorry, you are not lucky"Lambda > lucky7
"7 is the lucky number!"

Copy the code

Note, however, that if you move Lucky X before Lucky 7, you will never match Lucky 7.

  • Implement factorial with pattern matching:
factorial: :Int -> Int 
factorial 0 = 1 
factorial n = n * factorial (n - 1)
Copy the code
  • When defining schemas, always leave a universal schema at the end, otherwise you may make mistakes
  • Pattern matching of tuples
addVectors: : (Double.Double) - > (Double.Double) - > (Double.Double) 
addVectors a b = (fst a + fst b, snd a + snd b)
I can rewrite it as
addVectors: : (Double.Double) - > (Double.Double) - > (Double.Double) 
addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
Copy the code
  • It can be used in mode_Take your place. This one_It’s called a generic variable
  • You can usex: _To match the first element of the list, x, but remember to put parentheses, otherwise Haskell won’t understand it
head' :: [a] -> a 
head' [] = error "Can' t call head on an empty list, dummy!" Error interrupts the program
head' (x:_) = x The parentheses here are not tuple tokens
Copy the code
  • To match a list of only one element, use either [x] or (x:[])
  • To match a list of only two elements, use either [x,y] or (x:y:[]).
  • Matches a list of more than two elements with(x:y:_)Can’t use the form []
  • As mode:all@(x:items)All represents the entire x:items list for later reference

Guard/sentry guard

bmiTell: :Double -> String 
bmiTell weight height    
    | weight / height ^ 2< =18.5 = putStrLn "You're underweight, like a pole!"
    | weight / height ^ 2< =25.0 = putStrLn "If you're a normal weight, you must be an ugly bitch!" &emsp; &emsp;
    | weight / height ^ 2< =30.0 = putStrLn "You are over weight, lose weight fast, fat person!" &emsp; &emsp;
    | otherwise &emsp;                      = putStrLn "You're a pig!"
Copy the code

A BMI of less than 18.5 is a GUARD. Each guard statement is indented by at least one space. If none of the guards in the current mode has True and otherwise is not written, the next mode is entered.

where

You can use where to cache the results, or you can define other helper functions:

bmiTell: :Double -> String 
bmiTell weight height &emsp; &emsp;
    | bmi <= 18.5 = putStrLn "You're underweight, like a pole!"
    | bmi <= 25.0 = putStrLn "If you're a normal weight, you must be an ugly bitch!" &emsp; &emsp;
    | bmi <= 30.0 = putStrLn "You are over weight, lose weight fast, fat person!" &emsp; &emsp;
    | otherwise     = putStrLn "You're a pig!"
    where bmi = weight / height ^ 2
             x = "whatever"
             getBmi weight height = weight / height ^ 2
Copy the code

Where is only valid in the current schema.

Even without guard, you can use where in function definitions:

calcBmis: : [(Double.Double)] - > [Double] 
calcBmis xs = [bmi w h | (w, h)< - xs] &emsp; &emsp; 
    where bmi weight height = weight / height ^ 2
Copy the code

What can be used in this way

describeList :: [a] -> String
describeList ls = "The list is " ++ what ls
    where what [] = "empty."
             what [x] = "a singleton list."
             what xs = "a longer list."
Copy the code

Where what ls calls what function with ls as parameter.

let

ghci> 4 * (let a = 9 in a + 1) + 2 
42
Copy the code

Let is similar to WHERE except that WHERE allows us to bind variables only at the bottom of the function and is visible to the current schema. Let can appear anywhere, and the variables in let are only valid within IN.

Another difference is that let is an expression (with a value), while WHERE is not.

case

case <exp> of pattern1 -> result1
                    pattern2 -> result2
                    pattern3 -> result3
Copy the code

Pattern matching is just syntactic sugar for case, and pattern matching can only be used in function definitions, whereas case can be used anywhere.