DEV Community

Cover image for F# For Dummys - Day 12 Collections List
AllenZhu
AllenZhu

Posted on

F# For Dummys - Day 12 Collections List

Today we learn List, an immutable, ordered collection of elements of the same type
The term "ordered" here means that the list maintains the sequence in which elements were added, doesn't mean List is sorted

Create List

  • Explicitly specifying elements
let numbers = [1; 2; 3; 4; 5]
let names = ["Alice"; "Bob"; "Charlie"]
Enter fullscreen mode Exit fullscreen mode

the ; could be omit between elements if you write them in seperated lines

let list123 = [ 1 // first comment
                2 // second comment
                3 // third comment
                ]
Enter fullscreen mode Exit fullscreen mode

all elements should be the same type

let list123 = ["1"; 2; 3]
Enter fullscreen mode Exit fullscreen mode

the first elements is string, the rest is int, will get compile error:
All elements of a list must be implicitly convertible to the type of the first element, which here is 'string'. This element has type 'int'.(1,21)

  • Using a range
let numbers = [1..5] // Equivalent to [1; 2; 3; 4; 5]
let evenNumbers = [2..2..10] // Equivalent to [2; 4; 6; 8; 10]
Enter fullscreen mode Exit fullscreen mode
  • Using list comprehensions
let doubles = [for x in 1..5 -> x * 2] // Equivalent to [2; 4; 6; 8; 10]
let doubles = [for x in 2..2..10 -> x * 2] // Equivalent to [4; 8; 12; 16; 20]
Enter fullscreen mode Exit fullscreen mode

Get element of List

  • Using index
let numbers = [1; 2; 3]
let firstNumber = numbers.[0]  // first number 1
let thirdNumber = numbers.[2]  // third number 3

printfn "firstNumber %i thirdNumber %i" firstNumber thirdNumber
Enter fullscreen mode Exit fullscreen mode

if you use index not exist in List, will got index out of range exception

let numbers = [1; 2; 3]
let forthNumber = numbers.[4]

printfn "forthNumber %i" forthNumber
Enter fullscreen mode Exit fullscreen mode

compile error:
Unhandled exception. System.ArgumentException: The index was outside the range of elements in the list
the browser environment have bug about this exception

  • Using build-in method List.item
let numbers = [1; 2; 3]
let firstNumber =  numbers |> List.item 0

printfn "firstNumber %i" firstNumber
Enter fullscreen mode Exit fullscreen mode
  • head and tail List.head, get first element
let numbers = [1; 2; 3]
let head = numbers |> List.head

printfn "head %i" head
Enter fullscreen mode Exit fullscreen mode

List.tail, return list after removing the first element, not the last element

let numbers = [1; 2; 3]
let tail = numbers |> List.tail

printfn "tail %A" tail // tail [2; 3]
printfn "numbers %A" numbers // numbers [1; 2; 3]
Enter fullscreen mode Exit fullscreen mode

tail is a new List not including the first element, it won't change the value of original List numbers

Loop a List

  • for...in
let numbers = [1; 2; 3]

for number in numbers do
    printfn "Number: %d" number
Enter fullscreen mode Exit fullscreen mode
  • List.iter
let numbers = [1; 2; 3]

List.iter (fun number -> printfn "Number: %d" number) numbers
Enter fullscreen mode Exit fullscreen mode

fun define a lambda function here, it's equivalent to

let numbers = [1; 2; 3]
let printElement number = 
    printfn "Number: %d" number

List.iter printElement numbers
Enter fullscreen mode Exit fullscreen mode

Pattern Matching with List

let numbers0 = []
let numbers1 = [1]
let numbers3 = [1; 2; 3]
let describeList lst =
    match lst with
    | [] -> "The list is empty"
    | [x] -> sprintf "The list has one element: %d" x
    | [x; y] -> sprintf "The list has two elements: %d and %d" x y
    | x :: xs -> sprintf "The list starts with %d and has more elements" x

printfn "%s" (describeList numbers0)  // The list is empty
printfn "%s" (describeList numbers1)  // The list has one element: 1
printfn "%s" (describeList numbers3)  // The list starts with %d and has more elements
Enter fullscreen mode Exit fullscreen mode

Operate List

lists are indeed immutable, which means that you cannot modify a list after it has been created. Any operation that appears to modify a list (such as appending or prepending an element) actually creates a new list

  • Prepending an element
let originalList = [2; 3; 4]
let newList = 1 :: originalList

printfn "Original List: %A" originalList // Original List: [2; 3; 4]
printfn "New List: %A" newList //  New List: [1; 2; 3; 4]
Enter fullscreen mode Exit fullscreen mode
  • Appending an element
let originalList = [1; 2; 3]
let newList = originalList @ [4]

printfn "Original List: %A" originalList  // Original List: [1; 2; 3]
printfn "New List: %A" newList //  New List: [1; 2; 3; 4]
Enter fullscreen mode Exit fullscreen mode
  • Concatenate Lists
let originalList = [1; 2; 3]
let newList = List.append originalList [4]

printfn "Original List: %A" originalList
printfn "New List: %A" newList
Enter fullscreen mode Exit fullscreen mode
  • Filter

you can not remove an element in List directly as List is immutable, but you can filter element based on some condition, put them into a new List

let numbers = [1; 2; 3; 4; 5]
let evenNumbers = List.filter (fun x -> x % 2 = 0) numbers

printfn "evenNumbers: %A" evenNumbers // evenNumbers: [2; 4]
Enter fullscreen mode Exit fullscreen mode
  • Map

apply an operation to every elements in List, you can use loop/List comprehensions to achieve that, or use Map

let numbers = [1; 2; 3; 4; 5]
let doubleNumbers = List.map (fun x -> 2 * x) numbers

printfn "doubleNumbers: %A" doubleNumbers // doubleNumbers:  [2; 4; 6; 8; 10]
Enter fullscreen mode Exit fullscreen mode
  • Fold

"fold" or "compress" elements of List of into a single value by applying a function repeatedly

let numbers = [1; 2; 3; 4; 5]
let sum = List.fold (fun acc x -> acc + x) 0 numbers  // 15

printfn "sum: %i" sum // sum: 15
Enter fullscreen mode Exit fullscreen mode

step 1: acc = 0 and x = 1 New acc = 0 + 1 = 1
step 2: acc = 1 and x = 2 New acc = 1 + 2 = 3
step 3: acc = 3 and x = 3 New acc = 3 + 3 = 6
step 4: acc = 6 and x = 4 New acc = 6 + 4 = 10
step 5: acc = 10 and x = 5 New acc = 10 + 5 = 15

Top comments (0)