Active Patterns as a Library

Intro

Since my contract has ended, I have been using my unemployment to dig deeper into F#. Finally, it’s beginning to click for me. Now as I reason with my code, I recognize opportunities for some open source utilities.

As a result of my observation, I decided to contribute an active pattern library to NuGet. It’s Bizmonger.ActivePatterns.

module ValuesAP

let (|Equal|Different|) = function
    | v1, v2 when v1 = v2 -> Equal
    | _                   -> Different

module ListsAP

let (|None|One|Many|) (x:'a list) =
    match x with
    | x when x.Length > 1 -> Many
    | x when x.Length = 1 -> One
    | _                   -> None

module NumbersAP

let (|Positive|Neutral|Negative|) = function
    | x when x > 0 -> Positive
    | x when x < 0 -> Negative
    | _            -> Neutral

Here’s a sample of how to use the NumbersAP active pattern

let result = match -5 with
             | Positive -> "is positive"
             | Negative -> "is negative"
             | Neutral  -> "is neutral"

I think adding “AP” as a suffix to module names may be the way to go. Hence, this convention is used with JavaScript libraries. Thus, I plan on adding more active patterns to this package as I continue to build solutions.

Conclusion

In conclusion, since my contract has ended, I have been using my unemployment to dig deeper into F#. Finally, it’s beginning to click for me. Now as I reason with my code, I recognize opportunities for some open source utilities.

As a result of my observation, I decided to contribute an active pattern library to NuGet. It’s Bizmonger.ActivePatterns.

Advertisements
6 comments
  1. Congratulations! I hope you receive favorable feedback.

  2. Paul Westcitt said:

    List.Length is O(n), so more efficient (and nicer pattern matching) with the following:

    let (|None|One|Many|) (x:’a list) =
    match x with
    | [] -> None
    | [_] -> One
    | _ -> Many

    (Personally I don’t like the use of None there either, as None is “almost” a keyword, given the prevalent use of options through f# code… I mean this whole active pattern is overkill, but from a learning perspective it’s useful I guess…)

    • Thanks Paul. That’s great feedback. Hence, I am still learning. I never even considered performance. I will update the package with your feedback soon. Thanks again.

  3. Paul Westcitt said:

    And your Numbers one can be “enhanced” to deal with all numeric types (rather than just integers) if you make the function inline, and use LanguagePrimatives.GenericZero. Alternatively you could use the “sign” function which is static type generic already:

    let inline (|Positive|Neutral|Negative|) x =
    match sign x with
    | 1 -> Positive
    | -1 -> Negative
    | _ -> Neutral

    (note that you can only inline functions, thus the need to remove the function keyword, and replace with an argument)

    • Thanks Paul. I will have to check that out. I never knew sign was a built in function. Thanks for the feedback.

    • I still don’t understand what inline does. Any guidance?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: