# String Calculator Kata in F#

Since @theimowski introduced me to F# years ago, I wanted to try it someday. Finally, I feel like I'm ready for this challenge. And following @swyx suggestion to learn in public, I'll try to explain each step in the form of a blog post.

I will start with one of my favorites, yet nothing complicated, TDD kata - String calculator.

This article is the first part of a series:

And now it's the coding time!

## Adding single numbers

Following TDD rules, we will start with a test.

```
[<Fact>]
let ``Passing empty value returns 0`` =
let result = Add ""
Assert.Equal(0, result)
```

We see that the surface of our public API is just one method `Add(numbers: string): int`

Our first test case verifies the addition of an empty string, which, of course, should be equal to 0.
Making our test pass doesn't require much brainpower:

```
let Add (numbers: string): int = 0
```

Moving forward, we can add a few new tests for single values. We also convert our test to *Theory* in the process.

```
[<Theory>]
[<InlineData("", 0)>]
[<InlineData("5", 5)>]
[<InlineData("17", 17)>]
let ``Passing single number returns the same value`` (input, expected) =
let result = Add input
Assert.Equal(expected, result)
```

Of course, our current implementation isn't going to work. We can fix it with an elegant F# feature called pattern matching:

```
let Add (numbers: string): int =
match numbers.Length with
| 0 -> 0
| _ -> int numbers
```

## Numbers with a delimiter

Let's try a more complicated case. The next step is to add numbers separated by a comma. First, the test:

```
[<Fact>]
let ``Passing numbers with a seperator adds them`` () =
let result = Add "1,2"
Assert.Equal(3, result)
```

This time, we have to adjust the pattern matching we used earlier.

```
let Add (numbers: string): int =
match numbers.Length with
| 0 -> 0
| 1 -> int numbers
| _ -> numbers.Split([|','|], StringSplitOptions.RemoveEmptyEntries)
|> Array.map int
|> Seq.sum
```

Currently, we have three cases based on the length of our input.

- 0 for the input of length 0, which means an empty string
- returns the same value converted to integer when passed a single number
- And now the best part! We split the numbers by comma, map each digit in a string format to integer and finally sum the result. We do it in full F# force using the pipeline operator, which feeds output from the previous function to the next. Doesn't it look great?

Finally, we can add a few more tests to be sure:

```
[<Theory>]
[<InlineData("1,2", 3)>]
[<InlineData("5,8", 13)>]
[<InlineData("1,2,3,5,8,13", 32)>]
let ``Passing numbers with a seperator adds them`` (input, expected) =
let result = Add input
Assert.Equal(expected, result)
```

We implemented the first two steps from the Kata description. We can stop here for now. Full code is available on github.

In another episode, I will introduce custom delimiters.