Mark Needham

Thoughts on Software Development

Archive for the ‘.NET’ Category

F#: function keyword

with one comment

I’ve been browsing through Chris Smith’s Programming F# book and in the chapter on pattern matching he describes the ‘function’ key word which I haven’t used before.

It’s used in pattern matching expressions when we want to match against one of the parameters passed into the function which contains the pattern match.

For example if we have this somewhat contrived example:

let isEven value = match value with 
                    | x when (x % 2) = 0 -> true
                    | _ -> false

That could be rewritten using the function keyword to the following:

let isEven  = function 
               | x when (x % 2) = 0 -> true
               | _ -> false

It’s a relatively straight forward way to simplify code like this although one thing I noticed while looking back through some old code I’ve written is that if we use this syntax then we need to ensure that the parameter we want to pattern match against is passed as the last parameter to a function.

For example this function which is used to parse the arguments passed to a script was originally written like this:

let GetArgs initialArgs  =
    let rec find args matches =
        match args with
        | hd::_ when hd = "--" -> List.to_array (matches)
        | hd::tl -> find tl (hd::matches) 
        | [] -> Array.empty
    find (List.rev (Array.to_list initialArgs) ) []

If we want to use ‘function’ then we’d need to put ‘args’ implicitly as the second argument passed to the recursive ‘find’ function:

let GetArgs initialArgs  =
    let rec find matches =
        function
        | hd::_ when hd = "--" -> List.to_array (matches)
        | hd::tl -> find (hd::matches) tl
        | [] -> Array.empty
    find [] (List.rev (Array.to_list initialArgs) )

I’m not sure that the resulting code is necessarily more intention revealing if the function has more than one argument passed to it. The second version of this function could be very confusing if you didn’t know what the ‘function’ keyword actually did.

Written by Mark Needham

February 7th, 2010 at 2:54 am

Posted in F#

Tagged with

Functional C#: LINQ vs Method chaining

with 6 comments

One of the common discussions that I’ve had with several colleagues when we’re making use of some of the higher order functions that can be applied on collections is whether to use the LINQ style syntax or to chain the different methods together.

I tend to prefer the latter approach although when asked the question after my talk at Developer Developer Developer I didn’t really have a good answer other than to suggest that it seemed to just be a personal preference thing.

Damian Marshall suggested that he preferred the method chaining approach because it more clearly describes the idea of passing a collection through a pipeline where we can apply different operations to that collection.

I quite like that explanation and I think my preference for it would have probably been influenced by the fact that when coding in F# we can use the forward piping operator to achieve code which reads like this.

For example if we had a list and wanted to get all the even numbers, double them and then add them up we might do this:

[1..10] |>
List.filter (fun x -> x % 2 = 0) |>
List.map (fun x -> x * 2) |>
List.fold (fun acc x -> acc + x) 0

If I was in C# I’d probably do this:

Enumerable.Range(1, 10)
.Where(x => x % 2 == 0)
.Select(x => x * 2)
.Sum(x => x);

I found it quite difficult to work out what the equivalent LINQ syntax would be because I don’t use it but I think something like this would be what you’d need to write to do the same thing:

from x in Enumerable.Range(1, 10)
where x%2 == 0
select x * 2).Sum(x => x);

I’m not sure if there’s a way to do the sum within the LINQ statement or whether you need to do it using the method as I have here.

Even just writing this example I found that the way I had to write the LINQ code seemed quite counter intuitive for me with the way that I typically try to solve problems like this.

At least now thanks to Damian I now understand why that is!

Written by Mark Needham

February 5th, 2010 at 6:06 pm

Posted in .NET

Tagged with

Functional C#: Writing a ‘partition’ function

with 12 comments

One of the more interesting higher order functions that I’ve come across while playing with F# is the partition function which is similar to the filter function except it returns the values which meet the predicate passed in as well as the ones which don’t.

I came across an interesting problem recently where we needed to do exactly this and had ended up taking a more imperative for each style approach to solve the problem because this function doesn’t exist in C# as far as I know.

In F# the function makes use of a tuple to do this so if we want to create the function in C# then we need to define a tuple object first.

public class Tuple<TFirst, TSecond>
{
	private readonly TFirst first;
	private readonly TSecond second;
 
	public Tuple(TFirst first, TSecond second)
	{
		this.first = first;
		this.second = second;
	}
 
	public TFirst First
	{
		get { return first; }
	}
 
	public TSecond Second
	{
		get { return second; }
	}
}
public static class IEnumerableExtensions
{
	public static Tuple<IEnumerable<T>, IEnumerable<T>> Partition<T>(this IEnumerable<T> enumerableOf, Func<T, bool> predicate)
	{
		var positives = enumerableOf.Where(predicate);
		var negatives = enumerableOf.Where(e => !predicate(e));
		return new Tuple<IEnumerable<T>, IEnumerable<T>>(positives, negatives);
 
	}
}

I’m not sure of the best way to write this function – at the moment we end up creating two iterators to cover the two different filters that we’re running over the collection which seems a bit strange.

In F# ‘partition’ is on List so the whole collection would be evaluated whereas in this case we’re still only evaluating each item as it’s needed so maybe there isn’t a way to do it without using two iterators.

If we wanted to use this function to get the evens and odds from a collection we could write the following code:

var evensAndOdds = Enumerable.Range(1, 10).Partition(x => x % 2 == 0);
 
var evens = evensAndOdds.First;
var odds = evensAndOdds.Second;

The other thing that’s nice about F# is that we can assign the result of the expression to two separate values in one go and I don’t know of a way to do that in C#.

let evens, odds = [1..10] |> List.partition (fun x -> x % 2 = 0)

We don’t need to have the intermediate variable ‘evensAndOdds’ which doesn’t really add much to the code.

I’d be interested in knowing if there’s a better way to do this than what I’m trying out.

Written by Mark Needham

February 1st, 2010 at 11:34 pm

Posted in .NET

Tagged with , ,

DDD8: Mixing functional and object oriented approaches to programming in C#

with 7 comments

I did a presentation titled ‘Mixing functional and object oriented approaches to programming in C#’ at the Developer Developer Developer conference in Reading.

The slides from the talk are below:

I’ve not done many technical talks so far. My only previous attempt was a talk on F# one at the Sydney Alt.NET user group last year so I’m still learning how to do this effectively.

It was quite interesting reading through some of the feedback from twitter and several people pointed out that the content was too basic which was something I was concerned about while writing the talk:

OK. 30 mins into #ddd8 talk of functional vs OO approaches and I’ve been told one small thing I didn’t know.

#ddd8 finished @markhneedham talk… Good speaker,but but basic For me, the last 20% of the content should have been 80% of the talk

“If you want to learn more…” Er…yeah. I certainly want to learn more than I just did. #ddd8

Mark did a good job but difficulty lvl would help as it was quite basic. Missed caching bit looking at twitter. Doh!

Mark Needham’s talk on functional and OO at #DDD8 was OK, but the first 2/3 was too much of a simple intro.

The feedback I got in person was that the talk worked alright and there were a couple more positive comments on twitter too:

Great day at #ddd8 – really enjoyed Mark Needham’s functional programming session & testing ASP.Net with Ruby

Listening to @markneedham at #ddd8. He has a fantastic abilty to break things down and explain them :)

I think there were probably too many slides in the talk – I found myself pausing unnaturally so that I could move to the next slide which was also pointed out on twitter:

In my first session at #ddd8 on functional programming – loadsa slides – someone get the guy a remote!

I think I’ll probably go with less slides the next time – some of them weren’t adding much value anyway so I don’t think it would hurt too much to drop them.

Overall though it was a good experience for me getting the chance to put this talk together and I think I learnt a little more about better ways to understand the way we can use functional programming in C# by having the opportunity to prepare this.

Written by Mark Needham

January 31st, 2010 at 2:05 pm

Posted in .NET

Tagged with

Automapper: Don’t forget Mapper.Reset() at the start

with one comment

I wrote about my first thoughts using Automapper last week and although I realised that it makes use of the static gateway pattern we ran into a problem where two consecutive calls to a method using AutoMapper always returned the same value for one of the mappings.

The code was roughly like this:

public Bar CreateNewBar(Bar originalBar, string someNewValue)
{
	Mapper.CreateMap<Baz, Baz>()
      .ForMember(x => x.Id, opts => opts.Ignore())
      .ForMember(x => x.SomeProperty, opts => opts.MapFrom(source => someNewValue));
}

In our test everything worked fine because we were only calling the method once but when testing it out we were making multiple calls to the method and always receiving the same value for ‘someNewValue’.

I hadn’t quite pieced together that each mapping was probably only created once for each source/destination pair. I thought it would be recreated each time but browsing through the code we can see that’s what’s going on:

Configuration.cs

public IMappingExpression CreateMap(Type sourceType, Type destinationType)
{
   var typeMap = CreateTypeMap(sourceType, destinationType);
 
   return new MappingExpression(typeMap, _serviceCtor);
}
public TypeMap CreateTypeMap(Type source, Type destination)
{
   TypeMap typeMap = FindExplicitlyDefinedTypeMap(source, destination);
 
   if (typeMap == null)
   {
   ...
   }
   return typeMap;
}
private TypeMap FindExplicitlyDefinedTypeMap(Type sourceType, Type destinationType)
{
   return _typeMaps.FirstOrDefault(x => x.DestinationType == destinationType && x.SourceType == sourceType);
}

We put a test which called the method ‘CreateNewBar’ method twice to make sure that was actually the problem and then made use of the ‘Reset’ method on ‘Mapper’ to avoid the problem:

public Bar CreateNewBar(Bar originalBar, string someNewValue)
{
    Mapper.Reset();
	Mapper.CreateMap<Baz, Baz>()
      .ForMember(x => x.Id, opts => opts.Ignore())
      .ForMember(x => x.SomeProperty, opts => opts.MapFrom(source => someNewValue));
}

Written by Mark Needham

January 27th, 2010 at 7:57 am

Posted in .NET

Tagged with

Automapper: First thoughts

with 4 comments

I came across Jimmy Bogard’s Automapper library a while ago but hadn’t had the opportunity to try it out on a project until this week.

The problem we wanted to solve was relatively simple.

We had a domain object and we wanted to create a copy of that with one of the fields changed and all of the ids cleared from the object and any objects contained within it so that we could persist the new web of objects to the database.

We had a structure a bit like this:

public class Foo 
{
	public Bar Bar { get; set; }
	public Baz Baz { get; set; }
}

And wanted to create a copy of this object while changing one of the values on Baz:

Mapper.CreateMap<Foo, Foo>().ForMember(x => x.Id, opts => opts.Ignore());
Mapper.CreateMap<Bar, Bar>().ForMember(x => x.Id, opts => opts.Ignore());
Mapper.CreateMap<Baz, Baz>()
      .ForMember(x => x.Id, opts => opts.Ignore())
      .ForMember(x => x.SomeProperty, opts => opts.MapFrom(source => someNewValue));

It works really well although it took me a little while to realise that the ‘Mapper’ class was keeping track of what we’d set up via its methods internally.

Jimmy refers to this as the static gateway pattern which seems a little similar to the way that Rhino Mocks keeps track of expectations from what I remember from reading some of the code.

In general though I’ve got more used to expression builder style DSLs so it was interesting to see one which has been done with a different approach.

The next thing we had to work out was where that mapping code should go.

Since it’s completely about ‘Foo’ I originally thought it should go inside Foo on a static method which we could use to clone the object perhaps with an API like this:

public Foo CloneWith(string someNewValue)
{
	// mapping code in here
}

The problem with that is that it means we have a static dependency in our domain model and from reading Alistair Cockburn’s Hexagonal Architecture article I’ve come to believe that we should try to ensure that objects in our domain model don’t have dependencies on anyone else.

An alternative might be to have it on the object and then create an interface which represents the ability to clone Foo:

public Foo CloneWith(string someNewValue, ICanCloneAFoo fooCloner)
{
	return fooCloner.Clone();
}

The mapping code would then go on the implementer of ‘ICanCloneAFoo’. The discussions we had around this reminded me of a post I wrote about a year ago and the solution we decided to use was the same. We put the mapping code onto a mapper object.

It’s not a bad solution as it follows the convention that’s been done for other mapping problems in the code although as Mike pointed out, the code to clone the object is not as discoverable as it would be if it was on the object itself.

In that mapper we’re still calling the Automapper code directly which I think is fine although I’m not sure whether we’re quite adhering to the idea of wrapping 3rd party libraries, as suggested in Growing Object Oriented Software, and not allowing them to bleed into our code base.

It seems like in the case doing that might lead to more problems than it would solve.

Written by Mark Needham

January 22nd, 2010 at 11:21 pm

Posted in .NET

Tagged with

F#: Refactoring to sequence/for expressions

with 3 comments

Since I started playing around with F# one of the things I’ve been trying to do is not use the ‘for’ keyword because I was trying to avoid writing code in an imperative way and for loops are a big part of this for me.

Having read Jon Harrop’s solution to the word count problem where he made use of both sequence and for expressions I thought it’d be intersting to see what some of the code I’ve written would look like using that approach.

An example of a function that I wrote which could be rewritten the other way is the following:

let delimeters (value:string) = Regex.Matches(value, "\[([^]]*)\]") |> Seq.cast |> 
                                Seq.map (fun (x:Match) -> x.Groups) |>
                                Seq.map (fun x -> x |> Seq.cast<Group> |> Seq.nth 1) |>
                                Seq.map (fun x -> x.Value)

This could be written like this if we used a sequence expression instead of chaining map operations:

let delimeters (value:string) = seq { for m in Regex.Matches(value, "\[([^]]*)\]") do yield m.Groups.Item(0).Value }

One interesting thing I found about writing it like this was that I noticed that ‘GroupCollection’ had the ‘Item’ property on it which would let me get the match much more easily.

I completely missed that when I was writing the first solution so I’m not sure if that was just due to my lack of knowledge of that part of the API or whether the second approach actually encouraged me to explore more and therefore end up with a simpler solution.

Another example I found was this expression for getting the matches for a regular expression:

let regex pattern input = Regex.Matches(input, pattern) |> Seq.cast |> Seq.map (fun (x:Match) -> x.Value)

That can be simplified to the following with a sequence expression:

let regex pattern input = seq { for m in Regex.Matches(input, pattern) do yield m.Value }

One neat thing about using sequence expressions is that we don’t need to make use of ‘Seq.cast’ to convert a value to a typed sequence – we can just use it as it is.

The following function can be rewritten to just use a for expression:

let writeTo (path:string) (values:seq<string * int>) = 
    use writer = new StreamWriter(path)
    values |> Seq.map (fun (value, count) -> value + " " + count.ToString()) |> Seq.iter (fun x -> writer.WriteLine(x))

Like so:

let writeTo (path:string) (values:seq<string * int>) = 
    use writer = new StreamWriter(path)
    for (value,count) in values do writer.WriteLine(value + " " + count.ToString())

We eventually iterate through the sequence anyway so I think it’s more intention revealing to just do the iteration and mapping in one step.

This is a function from when I was writing the little Feedburner application:

let calculateWeeklyAverages =
    Seq.reverseSequence >>
    Seq.windowed days >>
    Seq.map (fun (entries:array<Entry>) -> 
                (entries.[0]).Date , entries |> Array.map (fun e -> e.Circulation |> toDecimal) |> Array.average ) >>
    Seq.reverseSequence

If we use a sequence expression it’d look like this:

let calculateWeeklyAverages entries =
    seq { for (e:array<Entry>) in (entries |> Seq.reverseSequence |> Seq.windowed days) do 
              yield ((e.[0]).Date, entries |> Array.map (fun e -> e.Circulation |> toDecimal) |> Array.average) } 
    |> Seq.reverseSequence

The resulting code is shorter but it seems to me like the focus when you read the code has moved to the line which yields the tuple whereas in the first version I find that I read the function as a whole.

I’ve not really used sequence expressions that much so it’s been interesting going through the code and seeing where they might be useful.

I found several places where I’d used lists because I find those easier to pattern match against but I wonder whether it would make sense to use sequences there as well.

Written by Mark Needham

January 14th, 2010 at 8:01 am

Posted in F#

Tagged with

F#: Refactoring to pattern matching

with 12 comments

I was looking through some of the F# code I’ve written recently and I realised that I was very much writing C# in F# with respect to the number of if statements I’ve been using.

I thought it would be interesting to see what the code would look like if I was able to refactor some of that code to make use of pattern matching instead which would be a more idiomatic way of solving the problem in F#.

The first example of if statements is in my post about my F# solution to Roy Osherove’s TDD Kata.

I originally wrote a parse function which was able to parse a string and give it’s decimal value or 0 if it couldn’t be parsed.

let parse value = 
    let (itParsed, value) = Decimal.TryParse value
    if (itParsed) then value else 0.0m

If we use a pattern match expression we’d end up with the following:

let parse value = match Decimal.TryParse value with | (true, value) -> value | (false, _) -> 0.0m

The neat thing about this approach is that we don’t need to store the result of the ‘Decimal.TryParse’ function as we did in my original version.

We could in theory also write it like this…

let parse value = match Decimal.TryParse value with | (true, value) -> value | (_, _) -> 0.0m

…but while that is slightly less code I quite like the other version because it’s a bit more intention revealing that 0 will be returned if we fail to parse the string. I think there’s less thinking needed to understand the code.

Another example is this bit of code:

let add value = if ("".Equals(value) or "\n".Equals(value)) then 0.0m
                else match digits value |> Array.filter (fun x -> x < 1000m) with 
                     | ContainsNegatives(negatives) -> raise (ArgumentException (buildExceptionMessage negatives))
                     | NoNegatives(digits)          -> digits |> Array.sum

If we convert that to use pattern matching we would get this:

let add value = match value with
                | "" -> 0.0m
                | "\n" -> 0.0m
                | value ->  match digits value |> Array.filter (fun x -> x < 1000m) with 
                            | ContainsNegatives(negatives) -> raise (ArgumentException (buildExceptionMessage negatives))
                            | NoNegatives(digits)          -> digits |> Array.sum

That’s maybe slightly easier to read mainly because of the splitting up of the two inputs which lead to a 0 result.

The final example of using if statements is the following bit of code:

let (|CustomDelimeter|NoCustomDelimeter|) (value:string) = 
	...
 
     if (value.Length > 2 && "//".Equals(value.Substring(0, 2))) then
         if ("[".Equals(value.Substring(2,1))) then CustomDelimeter(delimeters value)
         else CustomDelimeter([| value.Substring(2, value.IndexOf("\n") - 2) |])
     else NoCustomDelimeter(",")

The only way I could see how to make this use active patterns is on the boolean statements like so:

let (|CustomDelimeter|NoCustomDelimeter|) (value:string) = 
	...
 
    match (value.Length > 2 && "//".Equals(value.Substring(0, 2))) with
    | true -> match ("[".Equals(value.Substring(2,1))) with 
              | true  ->  CustomDelimeter(delimeters value)
              | false ->  CustomDelimeter([| value.Substring(2, value.IndexOf("\n") - 2) |])
    | false -> NoCustomDelimeter(",")

I quite like that it lines up the return values of the active pattern which seems to make it a bit more readable.

I think overall maybe the pattern matching versions are slightly more readable but maybe not by much. What do you think?

Written by Mark Needham

January 12th, 2010 at 1:33 am

Posted in F#

Tagged with

C# Object Initializer: More thoughts

with one comment

I wrote previously about my dislike of C#’s object initializer syntax and while I still think those arguments hold I came across an interesting argument for why it is a useful feature in Jeremy Miller’s MSDN article on creating internal DSLs in C#.

In the article Jeremy works through an example where he builds up a ‘SendMessageRequest’ first by using a fluent interface and then by making use of object initializer syntax.

The fluent interface example reads like this:

public void SendMessageFluently(FluentMessageSender sender)
 {
     sender
         .SendText("the message body")
         .From("PARTNER001").To("PARTNER002");
 }

Compared with the object initializer version which looks like this:

public void SendMessageAsParameter(ParameterObjectMessageSender sender)
 {
     sender.Send(new SendMessageRequest()
     {
         Text = "the message body",
         Receiver = "PARTNER001",
         Sender = "PARTNER002"
     });
 }

As Jeremy points out:

this third incarnation of the API reduces errors in usage with much simpler mechanics than the fluent interface version.

You need much less code to get the second version to work which my colleague Lu Ning pointed out to me when we were discussing how to use the builder pattern on a project we worked on together.

In general terms the benefit of using object initializer is that we get more expressive code and the intent of that code is clearer than we would be able to achieve by constructing the object using its constructor.

The down side is that it creates a mentality of using setters and the initialisation of the object potentially leaves several fields with null values.

We then end up either getting unexpected null reference exceptions throughout the code or we code defensively and check for nulls whenever we try to access one of the properties. Seeing as one of the goals of the object initializer is to reduce the code we write it’s somewhat ironic that we end up writing this extra code to ensure the object has been setup correctly.

One way to solve this is to make use of tiny types so that the API is still expressive even though what we want to pass in is a string. That takes more code but it allows us to make use of the constructor to construct the object which is something which seems to have lost favour.

C# 4.0 will introduced named parameters into the language which seems like it will help us achieve expressiveness of our code without having to write extra classes and code to achieve this.

* Updated the examples as I had them the wrong way around. Thanks to Corey Haines and Mike Wagg for pointing it out.

Written by Mark Needham

January 10th, 2010 at 6:52 pm

Posted in .NET

Tagged with ,

Roy Osherove’s TDD Kata: An F# attempt

with 5 comments

As I’ve mentioned in a few of my recent posts I’ve been having another go at Roy Osherove’s TDD Kata but this time in F#.

One thing I’ve been struggling with when coding in F# is working out how many intermediate variables we actually need. They can be useful for expressing intent better but they’re clutter in a way.

I’ve included my solution at the end and in the active pattern which determines whether or not we have a custom delimeter defined in our input string I can’t decide whether or not to create a value to represent the expressions that determine that.

3
4
5
6
7
8
9
10
    let (|CustomDelimeter|NoCustomDelimeter|) (value:string) = 
        ...
        let hasACustomDelimeter = value.Length > 2 && "//".Equals(value.Substring(0, 2))
 
        if (hasACustomDelimeter) then
            if ("[".Equals(value.Substring(2,1))) then CustomDelimeter(delimeters value)
            else CustomDelimeter([| value.Substring(2, value.IndexOf("\n") - 2) |])
        else NoCustomDelimeter(",")

In a way it’s quite obvious that the expression on line 3 is what we’re using to determine if the input string has a custom delimeter because we state that on the next line.

    let (|CustomDelimeter|NoCustomDelimeter|) (value:string) = 
        ...
        if (value.Length > 2 && "//".Equals(value.Substring(0, 2))) then
            if ("[".Equals(value.Substring(2,1))) then CustomDelimeter(delimeters value)
            else CustomDelimeter([| value.Substring(2, value.IndexOf("\n") - 2) |])
        else NoCustomDelimeter(",")

I can’t decide which I prefer so any thoughts on that would be welcome.

I ran into a bit of trouble trying to make the following requirement work because my original parse function was hiding the fact that the code was failing on this step:

Delimiters can be of any length with the following format:  ā€œ//[delimiter]\nā€ for example: ā€œ//***\n1***2***3ā€ should return 6

The parse function was originally defined to returns a zero value if it failed to parse the string which meant that the function which decomposed the string into a sequences of numbers could fail and we wouldn’t see an exception, just a failing test.

    let parse value = 
        let (itParsed, value) = Decimal.TryParse value
        if (itParsed) then value else 0.0m

Having the function defined like this simplified the code a bit because I didn’t need to deal with ignoring some characters at the beginning of the string when a custom delimeter was being specified.

One of the instructions for the exercise is to focus on writing tests for the valid inputs and not for invalid inputs which I initially struggled with. Usually if I was test driving code I would have written tests against invalid inputs to help me drive out the design.

Once I started focusing on just making the test past instead of finding a generic solution for the whole problem this became much easier and I didn’t need to test with the invalid inputs.

I wrote tests for the code in C# using NUnit so that I could run the tests from Resharper. I still haven’t found a good way to run automated tests from inside Visual Studio when they’re written in F# otherwise I’d have probably just done that.

All the tests I wrote were against the ‘add’ function but the way the code is written at the moment it would be possible to write tests against the other functions directly if I wanted to.

If I was working in C# perhaps some of those functions would be classes and I would write tests directly against those but I haven’t done that here and I’m not sure whether it is necessary. ‘digits’ is the only function where that would seem to add value.

This is the code I’ve got at the moment:

module FSharpCalculator
    open System
    open System.Text.RegularExpressions
 
    let split (delimeter:array<string>) (value:string) = value.Split (delimeter, StringSplitOptions.None)
    let toDecimal value = Decimal.Parse value
 
    let (|CustomDelimeter|NoCustomDelimeter|) (value:string) = 
        let delimeters (value:string) = Regex.Matches(value, "\[([^]]*)\]") |> Seq.cast |> 
                                        Seq.map (fun (x:Match) -> x.Groups) |>
                                        Seq.map (fun x -> x |> Seq.cast<Group> |> Seq.nth 1) |>
                                        Seq.map (fun x -> x.Value) |>
                                        Seq.to_array
 
        if (value.Length > 2 && "//".Equals(value.Substring(0, 2))) then
            if ("[".Equals(value.Substring(2,1))) then CustomDelimeter(delimeters value)
            else CustomDelimeter([| value.Substring(2, value.IndexOf("\n") - 2) |])
        else NoCustomDelimeter(",")    
 
    let digits value = match value with 
                       | CustomDelimeter(delimeters)  -> value.Substring(value.IndexOf("\n")) |> split delimeters  |> Array.map toDecimal 
                       | NoCustomDelimeter(delimeter) -> value.Replace("\n", delimeter) |> split [|delimeter |] |> Array.map toDecimal
 
    let buildExceptionMessage negatives = 
        sprintf "No negative numbers allowed. You provided %s" (String.Join(",", negatives |> Array.map (fun x -> x.ToString())))
 
    let (|ContainsNegatives|NoNegatives|) digits =
        if (digits |> Array.exists (fun x -> x < 0.0m)) 
        then ContainsNegatives(digits |> Array.filter (fun x -> x < 0.0m))
        else NoNegatives(digits)
 
    let add value = if ("".Equals(value) or "\n".Equals(value)) then 0.0m
                    else match digits value |> Array.filter (fun x -> x < 1000m) with 
                         | ContainsNegatives(negatives) -> raise (ArgumentException (buildExceptionMessage negatives))
                         | NoNegatives(digits)          -> digits |> Array.sum

Written by Mark Needham

January 10th, 2010 at 1:46 am

Posted in F#

Tagged with ,