Monday, May 17, 2010

More Active Pattern Activity

Here are some more samples I came up with while practicing with active patterns. Again, I'm not sure I would ever implement any of these in particular; there may be better ways. But still, I could see where a couple of them would be handy, and my main purpose was to become comfortable with using active patterns.

Forgive my unexciting examples, it was late on a Sunday night, lol.

(As always, presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)
// Explicit empty; just for fun.
let inline (|Empty|NonEmpty|) (s:string) =
  match System.String.IsNullOrEmpty(s) with
  | true -> Empty
  | _ -> NonEmpty
 
 
// Return Some() if s starts with p, else None.
let inline (|StartsWith|_|) (p:string) (s:string) =
  match s with
  | Empty -> None
  | _ ->
    match s.StartsWith(p) with
    | true -> Some()
    | _ -> None
 
 
// Return Some(p,s') if s starts with p, else None,
// where s' is the remainder of s.
let inline (|BeginsWith|_|) (p:string) (s:string) =
  match s with
  | Empty -> None
  | _ ->
    match s.StartsWith(p) with
    | true -> Some((p,s.Substring(p.Length)))
    | _ -> None
 
 
// Return (p,s') if s starts with p, else ("",s),
// where s' is the remainder of s.
let inline (|SplitStart|) (p:string) (s:string) =
  match s with
  | Empty -> ("",s)
  | _ ->
    match s.StartsWith(p) with
    | true -> (p,s.Substring(p.Length))
    | _ -> ("",s)
 
 
// Return index if s contains p, else None,
let inline (|IndexOf|_|) (p:string) (s:string) =
  match s with
  | Empty -> None
  | _ ->
    match s.IndexOf(p) with
    | -1 -> None
    | i -> Some(i)
 
 
let test0 (s:string) =
  match s with
  | StartsWith "zero" -> "zero"
  | StartsWith "one" -> "one"
  | _ -> ""
 
let test1 (s:string) =
  match s with
  | BeginsWith "zero" (h,t) -> t+h
  | BeginsWith "five" (h,t) -> t+h
  | _ -> s
 
let test2 (s:string) =
  match s with
  | SplitStart "zero" (h,t) -> t+h
 
let test3 (s:string) =
  match s with
  | IndexOf "zero" (i) -> s.Substring(i)
  | IndexOf "seven" (i) -> s.Substring(i)
  | _ -> ""
 
 
let tests = [
  test0;
  test1;
  test2;
  test3 ]
 
let strings = [
  "zero two";
  "one two seven four";
  "five two";
  "three two" ]
 
let result =
  List.map 
    (fun t -> List.map t strings)
    tests 
 
printf "Done."

No comments: