F# String extension methods rather than using RegEx
In my previous post I talked about some extension methods for string checking:
But what would be a post if there was not a F# equivalent.
Interestingly the ability to perform checks on each character in a string is actually already supported by F#; using the String.forall:
String.forall Char.IsLetter "AO"
However, one can also easily create the same String extension methods, as in the previous post, in F#:
namespace FSharp.StringExtensions
open System
open Microsoft.FSharp.Core
module StringAllChecks =
// private methods to perform the comparisions
let private isAllValidation (value:string) (charFunc:char -> bool) (length:int option) =
let stringLength = defaultArg length 0
if (stringLength < 0) then invalidArg "length" (sprintf "Length must be positive but was %d." length.Value)
if (String.IsNullOrWhiteSpace(value)) then
false
elif (not (String.forall charFunc value)) then
false
elif (stringLength > 0 && value.Length <> stringLength) then
false
else
true
type String with
member this.IsAllLetter(?length:int) =
isAllValidation this Char.IsLetter length
member this.IsAllDigit(?length:int) =
isAllValidation this Char.IsDigit length
member this.IsAllLetterOrDigit(?length:int) =
isAllValidation this Char.IsLetterOrDigit length
member this.IsAllNumber(?length:int) =
isAllValidation this Char.IsNumber length
member this.IsAllLower(?length:int) =
isAllValidation this Char.IsLower length
member this.IsAllUpper(?length:int) =
isAllValidation this Char.IsUpper length
The extension methods are more explicit in F#, compared to the C# implementation, as one merely extends the appropriate type; in this case String.
One of the main differences between this and the C# implementation is around the use of String.forall method rather than the LINQ IEnumerable<T>.All method. Also, an option parameter is used for the string length specification.
These extensions methods allow one to write statements such as:
let trueAllLetter = "AO".IsAllLetter()
let trueAllDigit = "12".IsAllLetter()
let falseAllLetter = "A0".IsAllLetter()
let falseAllDigit = "O1".IsAllLetter()
The main downside to the F# implementation is that the extension methods can only be consumed from F#.