How does pattern matching work behind the scenes in F#?

前端 未结 4 1170
花落未央
花落未央 2021-02-12 13:25

I am completely new to F# (and functional programming in general) but I see pattern matching used everywhere in sample code. I am wondering for example how pattern matching actu

4条回答
  •  爱一瞬间的悲伤
    2021-02-12 13:33

    It depends on what kind of pattern matching do you mean - it is quite powerful construct and can be used in all sorts of ways. However, I'll try to explain how pattern matching works on lists. You can write for example these patterns:

    match l with
    | [1; 2; 3] ->  // specific list of 3 elements
    | 1::rest ->    // list starting with 1 followed by more elements
    | x::xs ->      // non-empty list with element 'x' followed by a list
    | [] ->         // empty list (no elements)
    

    The F# list is actually a discriminated union containing two cases - [] representing an empty list or x::xs representing a list with first element x followed by some other elements. In C#, this might be represented like this:

    // Represents any list
    abstract class List { }
    // Case '[]' representing an empty list
    class EmptyList : List { }
    // Case 'x::xs' representing list with element followed by other list
    class ConsList : List {
      public T Value { get; set; } 
      public List Rest { get; set; }
    }
    

    The patterns above would be compiled to the following (I'm using pseudo-code to make this simpler):

    if (l is ConsList) && (l.Value == 1) &&
       (l.Rest is ConsList) && (l.Rest.Value == 2) &&
       (l.Rest.Rest is ConsList) && (l.Rest.Rest.Value == 3) &&
       (l.Rest.Rest.Rest is EmptyList) then
       // specific list of 3 elements
    else if (l is ConsList) && (l.Value == 1) then
       var rest = l.Rest;
       // list starting with 1 followed by more elements
    else if (l is ConsList) then
       var x = l.Value, xs = l.Rest;
       // non-empty list with element 'x' followed by a list
    else if (l is EmptyList) then 
       // empty list (no elements)
    

    As you can see, there is no looping involved. When processing lists in F#, you would use recursion to implement looping, but pattern matching is used on individual elements (ConsList) that together compose the entire list.

    Pattern matching on lists is a specific case of discriminated union which is discussed by sepp2k. There are other constructs that may appear in pattern matching, but essentially all of them are compiled using some (complicated) if statement.

提交回复
热议问题