I think there’s a time for all of us when we sat down to write a piece of code and it worked perfectly first time, and we thought to ourselves that perhaps we might just make developers of ourselves yet – shortly before we found an edge case that wasn’t covered, or irreparably broke everything with our overconfidence.

I’ve recently been going through Project Euler problems again – having solved a great many of them in C# – and solving them in F#. And it’s been amazing. That feeling of things working first time has become more commonplace than it has any right to be, particularly in a language that I’m (relatively) unfamiliar with and when I’m writing code with no IDE niceties (LinqPad); and since I’m fairly certain that I haven’t become insanely competent at overnight, I can’t help but feel that it can only be attributed to the language and paradigm itself.

If I wasn’t before, I’m certainly feeling the love for F# now.

### For example…

Problem 13 is incredibly simple if you have an arbitrary-sized integer type, and while I could easily use `Math.bigint`

, I thought it might be a nice exercise to create my own. Now, the code below may not be the prettiest in the world, and it certainly isn’t the most efficient, but for something that I knocked together in a few minutes in my spare time without taking too much care over… it worked first time! (Well… *almost* anyway… the first time around I forgot the case where the digits had all been dealt with but `carried`

wasn’t zero.) Hopefully that doesn’t undermine my point too much, because I’ve truly been impressed by how much I feel helped rather than hindered by the language.

type BigNum (digits: int list) = // digits: list of decimal digits smallest-biggest static let carryDigits digits = let rec carryDigits digits processed carried = let getDigitAndCarry next = next % 10, next / 10 match digits with | [] -> match carried with | 0 -> processed // all done and nothing more to carry | _ -> // digits all done, but still carrying left let digit, carriedNext = getDigitAndCarry carried carryDigits digits (digit :: processed) carriedNext | _ -> // keep going...! let next = (List.head digits) + carried let digit, carriedNext = getDigitAndCarry next carryDigits (List.tail digits) (digit :: processed) carriedNext carryDigits digits [] 0 |> List.rev member this.digits = carryDigits digits static member Create (s: string) = let numStringToList (s: string) = s |> Seq.map (string >> Int32.Parse) |> List.ofSeq |> List.rev let digits = numStringToList s BigNum(digits) static member (+) (a: BigNum, b: BigNum) = let matchLengths list1 list2 = let extend list toLength = let lengthToAdd = max 0 (toLength - List.length list) let zeroes = [for i in 1..lengthToAdd -> 0] list @ zeroes let list1' = extend a.digits (List.length list2) let list2' = extend b.digits (List.length list1) list1', list2' let resultDigits = matchLengths a.digits b.digits ||> List.zip |> List.map (fun (a,b) -> a + b) |> carryDigits BigNum(resultDigits) override this.ToString() = List.fold (fun acc x -> string(x) + acc) "" digits