List is the basis of functional programming (FP. In fact, the important representative of FP is the name of lisp.
Processing ", its inventor, John
McCarthy's paper published in 1960 showed us how to construct a complete programming language based on just a few simple operators and a sign that represents a function.
One idea is to use a simple data structure list to represent code and data.
The linked list is one of the main data structures of lisp, and the source code of lisp is also composed of the list. The list type in F # is represented as a linked list, which is significantly different from the array and generic list <t> types in C. The linked list can be represented in the following figure:
First, let's take a look at the basic operations in the FP list (the code is implemented by F ).
Basic list operations
Cons: the abbreviation of "construct", used to construct a list, meaning that an element is added to the beginning of the list. We first specify an empty table as [], and then specify the operator ":" to indicate the cons operation, so that we can construct any list. For example:
F # code-list cons operations
Let emptylist = [] // []
Let oneitem = 3: [] // [3]
Let twoitems = 2: oneitem // [2; 3]
Let threeitems = 1: twoitems // [1; 2; 3]
We can see how to create a list step by step through the "cons" operation.
Car: It indicates "Contents of the address part of the register", that is, the first element of the list. F # uses the list module's HD (head) function to perform the car operation:
F # code-list car operations
Let stringlist = ["no"; "one"; "really"; "listens to"; "anyone else."]
List. HD stringlist // "no"
CDR: It indicates "Contents of the decrement part of the register", that is, an element other than the first element in the list. F # uses the TL (tail) function of the List module to perform the CDR operation:
F # code-list CDR operation
Let stringlist = ["no"; "one"; "really"; "listens to"; "anyone else."]
List. TL stringlist // ["one"; "really"; "listens to"; "anyone else."]
With these three basic operations, other operations can be deduced. For example:
Concat: this operation is used to connect two lists. In F #, use the "@" operator to perform this operation.
F# Code
let list1 = [2; 3; 4]
let list2 = [5; 6; 7]
let largeList = list1 @ list2
print_any largeList // [2; 3; 4; 5; 6; 7]
Length: number of elements in the check list. Use the length function of the List module in F:
F# Code
let list1 = [2; 3; 4]
List.length list1 // 3
Nth: this operation returns the nth element of the list. In F #, use the nth function of the List module:
F# Code
let list1 = [2; 3; 4]
List.nth list1 2 // 4
Here the code is used to obtain the element whose index (based on 0) is 2 in list1, and 4 is returned.
Now let's take a look at the important functions in the list module:
List module (Microsoft. fsharp. Collections. List) Function
List. Rev: Obviously, it can flip a list. Note that this function creates a copy of the entire list, so pay attention to performance issues.
List.zip: the signature of this function is a' list-> B 'list-> (a' * B') List. The two lists are packaged into a list of tuples:
F# Code
print_any(List.zip [1; 2] ["one"; "two"]) // [(1, "one"); (2, "two")]
List. exists: the signature type of this function is (a'-> bool)-> a' list-> 'a, as the name suggests, it is used to check whether the list contains elements that meet the specified predicate function.
List. Find: the signature type of this function is (a'-> bool)-> a' list->
'A, we can see that it accepts two parameters. The first parameter is the predicate function, the second parameter and the input list. In this way, the find function checks the list elements one by one to see if they meet the requirements described above.
If a predicate function is found, the value of this element is returned. Otherwise, an exception is thrown.
F# Code
let result = List.find (fun i -> i * i = 64) [1..10]
print_int result // 8
Check every number in [1 .. 10] and return 8. However, if no element is found, keynotfoundexception is thrown. You can use tryfind, which is similar to the tryparse method in C.
List. filter: The parameters accepted by this function are similar to those of the find function. However, this function filters list elements and constructs all elements that meet the predicate function into a list and returns the result:
F# Code
let list3 = List.filter (fun i -> i % 2 = 0) [1..20]
print_any list3 // [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
In addition, there are powerful aggregate functions (aggregate operators), that is, ITER, map, and fold. (In fact, the set, seq, option, and array modules in F # support these three operations)
List. ITER: This function applies each element in the enumeration list to a specified function, for example:
F# Code
List.iter (fun i -> printfn "List contains %d" i) [1..5]
Output result:
F# Code
List contains 1
List contains 2
List contains 3
List contains 4
List contains 5
List. MAP: map function converts a list to another one. Its signature type is:
Type Infomation
(‘a –> ‘b) –> ‘a list –> ‘b list
This is easy to understand. You can apply functions to the elements of the first list one by one to get a new list:
F# Code
let x = List.map (fun i -> i * (-1)) [1..5]
printfn "%A" x // [-1; -2; -3; -4; -5]
List. Fold: among the three functions, fold is the most powerful, but also the most complex. Its function can be understood as follows: assume that we have three values: Initial Value basevalue, Function
Fun, list, access each element in the list one by one, apply the function fun to it, accumulate the execution result of fun to basevalue, fold will basevalue
Returns the final value. You can use the left-to-right or right-to-left mode to access the list one by one. Therefore, the fold function has two implementations: fold_left and fold_right.
F# Code
let accumulate acc x = acc + x
let totalList = List.fold_left accumulate 0 [1..100]
printfn "1+2+..+100 = %d" totalList // 5050
Here, the basevalue is 0, the function is accumulate, the list is [1 .. 100], and the final result is 5050.
Combination of list and pattern matching and Recursion
In the beginner list, it is easy to look at it like the set type in C. I recently learned about Haskell and impressed it with its purity and elegance. The list part of it uses pattern matching and delivery in large quantities.
This process also gave me a new understanding of the list. Compared with the list module of F #, Haskell provides additional list operation functions. Here I want to implement these functions in F # To see how to complete
Combined Use List and pattern matching and recursion.
Take: two parameters, one number and one list are accepted to obtain a new list composed of the specified number of elements starting with the list:
F# Code
let rec take (count: int) (l: 'a list) =
match l with
| _ when count <= 0 -> []
| [] -> []
| x :: xs -> x :: take (count - 1) xs
let list1 = [1; 2; 3; 4; 5]
print_any(take 0 list1) // []
print_any(take 1 list1) // [1]
print_any(take 3 list1) // [1; 2; 3]
Recursion and pattern matching are also used here. If count is less than or equal to 0, an empty list is returned; otherwise, an element with a specified number counted from the beginning is returned.
Drop: This function also accepts two parameters, removing the specified number of elements from the beginning of the List, and returning the list composed of the remaining elements:
F# Code
let rec drop (count: int) (l: 'a list) =
match l with
| _ when count <= 0 -> l
| [] -> []
| head :: tail -> drop (count - 1) tail
let list1 = [1; 2; 3; 4; 5]
print_any(drop 0 list1) // [1; 2; 3; 4; 5]
print_any(drop 1 list1) // [2; 3; 4; 5]
print_any(drop 5 list1) // []
If count is less than or equal to 0, return to the original list; otherwise, remove the specified number of elements. Head and tail are used here to make the code more readable.
Through the take and drop functions, we can see that we must first understand the list as a linked list, and then apply recursion and pattern matching on this basis to complete many complex operations.
Summary
This article describes the list operations in functional programming (FP. The first is the list of three basic operations in functional programming. On this basis, we can export other operations. Then we will introduce F #.
Important functions in the list module. At last, two user-defined functions are used to demonstrate how to combine list, recursion, and pattern matching. By the way, it is strongly recommended that you learn Haskell to understand fp
The basic idea is that in F #, it is easy to use imperative programming to write programs. This flexibility often leads to a deviation from FP, especially when you are new to FP. This is like the process of learning English. Imagine, for example
If you are airdropped to the United States (or other English-speaking countries), will your English progress be much faster?