Can someone help me compare using F# over C# in this specific example (IP Address expressions)?

Posted by Phobis on Stack Overflow See other posts from Stack Overflow or by Phobis
Published on 2010-05-12T15:23:22Z Indexed on 2010/05/12 16:04 UTC
Read the original article Hit count: 192

Filed under:
|
|
|
|

So, I am writing code to parse and IP Address expression and turn it into a regular expression that could be run against and IP Address string and return a boolean response. I wrote the code in C# (OO) and it was 110 lines of code. I am trying to compare the amount of code and the expressiveness of C# to F# (I am a C# programmer and a noob at F#). I don't want to post both the C# and F#, just because I don't want to clutter the post. If needed, I will do so.

Anyway, I will give an example. Here is an expression:

192.168.0.250,244-248,108,51,7;127.0.0.1

I would like to take that and turn it into this regular expression:

((192.168.0.(250|244|245|246|247|248|108|51|7))|(127.0.0.1))

Here are some steps I am following:

Operations:

Break by ";" 192.168.0.250,244-248,108,51,7 127.0.0.1

Break by "." 192 168 0 250,244-248,108,51,7

Break by "," 250 244-248 108 51 7 Break by "-" 244 248

I came up with F# that produces the output. I am trying to forward-pipe through my operations listed above, as I think that would be more expressive. Can anyone make this code better? Teach me something :)

open System

let createItemArray (group:bool) (y:char) (items:string[]) = 
  [|
    let indexes = items.Length - 1
    let group = indexes > 0 && group
    if group then
      yield "("
    for i in 0 .. indexes do
      yield items.[i].ToString()
      if i < indexes then
        yield y.ToString()
    if group then
      yield ")"
  |] 

let breakBy (group:bool) (x:string) (y:char): string[] = 
  x.Split(y)
    |> createItemArray group y 

let breakItem  (x:string) (y:char): string[] = breakBy false x y
let breakGroup  (x:string) (y:char): string[] = breakBy true x y

let AddressExpression address:string = 
    let builder = new System.Text.StringBuilder "("
    breakGroup address ';'
    |> Array.collect (fun octet -> breakItem octet '.')
    |> Array.collect (fun options -> breakGroup options ',')
    |> Array.collect (fun (ranges : string) -> 
                            match (breakGroup ranges '-') with
                            | x when x.Length > 3
                              -> match (Int32.TryParse(x.[1]), Int32.TryParse(x.[3]))    with
                                  | ((true, a) ,(true, b))
                                      -> [|a .. b|]
                                          |> Array.map (int >> string)
                                          |> createItemArray false '-'
                                  | _ -> [|ranges|]
                            | _ -> [|ranges|]
                    )
    |> Array.iter (fun item ->
                    match item with
                    | ";" -> builder.Append ")|("
                    | "." -> builder.Append "\."
                    | "," | "-" -> builder.Append "|"
                    | _ -> builder.Append item
                    |> ignore
                  )
    builder.Append(")").ToString()

let address = "192.168.0.250,244-248,108,51,7;127.0.0.1"
AddressExpression address

© Stack Overflow or respective owner

Related posts about F#

Related posts about c#