Navigate / search

Why do cars have brakes?

Why do cars have brakes?

I noticed this question on Jon Jagger’s blog and I was delighted with myself that I managed to get the “right” answer without peeking.

Stop reading right now, have a think about it, then head on over to Jon’s blog to see what he has to say on the topic.

Then, if you want, read the drivel that I’ve posted below.

How would you drive if your car didn’t have brakes? Perhaps you’d stick to 5mph because at that speed you can use the wall of the building you’re visiting, or a nearby tree to stop. On a school run 5mph is probably a safe speed at which to throw an average 8 year old from a moving car. Maybe 10mph if they are sturdy.

Brakes allow you to travel faster because you have the power to stop, or slow to safe child throwing speed at will.

Brakes allow you to drive faster but react to exceptions, like a child running in front of the car. Even with brakes you can get into trouble by being reckless, but all things being equal a car with brakes can be driven faster more safely than a car without.

Since the point of driving is the getting around, and not the stopping, it would be odd if the entire driving process was limited by our lack of stopping ability. We add brakes to liberate ourselves from that worry.

In Software terms our goal is to build software, not to catch or fix bugs. So we adopt processes like automates tests, executable specifications, continuous integration, automated builds and deployment, not for the sake of what these things do, but so that we can focus on the building of the software and know that if we introduce a bug the tests will stop us, and guide us straight to the problem, if we break the build the build server will tell us.

If you drive a software process with no brakes, you either have to go 5mph, regression testing everything manually building manually, deploying manually, resolving deployment conflicts manually.

Or, you can be reckless, you can belt along as fast as you like hurling builds into production without a care for the consequences. In software terms you are a parent who throws your kid out the window as you whiz by their school at 40mph, or hurtles into junctions knowing that if the unexpected happens, you have no hope of averting disaster.

Sometimes that things that “slow us down”, or even “stop us in our tracks” are there to enable us to go faster.

Music Moments

A break from the tech stuff tonight and a post I’ve thought about for a long time but never got around to writing. I’ve noticed over the years that there are a handful of “moments” in music that I never tire of hearing. By “moment” I don’t mean a favourite song, or album or favourite lyrics or favourite tune. I literally mean a moment, a word maybe a note, or a syllable.

I don’t really understand why these stand out for me, they just do. Drop me a comment if you too have recognised this phenomenon of musical moments, and let me know what some of your favourites are. I doubt I’m the only one, at least I hope I’m not. Even more interestingly, let me know if any of the moments I describe below strike a chord for you too.

I don’t really want comments saying “jeez your taste in music stinks, try listening to this Japanese group of blind blues musicians that nobody has heard of”. I’m too old for that shit. I’m no longer interested in whether a particular set of soundwaves vibrate my eardrums better than yours. It’s just music.

Without further ceremony, here are some favourite musical moments.

  1. Do You Want To Know A Secret – The Beatles
  2. 37 seconds into this Beatles Track George Harrison sings “I’m in love with you” and it’s the “I’m” that always gets me. For the rest of the song his vocal is soft, melodic, but for that one word it rasps a little, there’s an edge to it. He sings that line exactly the same way twice more in the less than 2 minutes that the song runs to. I don’t think I’ll ever tire of it. The vocal on this stood out for me as a kid before I realised it was George singing.

  3. Fairytale of New York – The Pogues and Kirsty MacColl
  4. “Cars Big as Bars”. There’s an almost imperceptible wobble in MacColl’s voice as she sings the word Bars, I honestly don’t know if it’s really there or if It’s something I hear in my head when she sings, but I love the way she delivers that line, and that word in particular. I did a search this Christmas for as many covers of the song as I could find and really nobody comes close to the performance of MacGowan and MacColl. The whole songs is a masterpiece, but the moment in the song I like most is “Bars”

  5. Cathy’s Clown – The Everly Brothers
  6. The Harmonies on this are great, I didn’t think it was possible to drag a one syllable word like “Love” out to the extent that they do, but the line I like most is “I Die Each Time”. I have no idea why I like it, or why in a song that I like generally that that line would stand out, but it does.

  7. Blue Moon of Kentucky – Elvis Presley
  8. When you listen to the original Bill Monroe Waltz and then hear what the song became in Sun Studios it’s hard not to wonder what it must have been like to turn on a radio in the Summer of 1954 and hear it. I love the whole song, but the line that stands is “Keep shining bright” in the opening verse. It’s got reverb on the vocals, it’s got the slapping on the bass, that Rock and Roll Sound.

  9. Boys Of Summer – Don Henley
  10. This song nails Summer in the way Fairytale of New York nails Christmas. 3 mins 4 seconds in there’s a little guitar riff that I like. I only say that because it’s too obvious to claim to like the “I can see you” line, but dammit I do, I like that line.

  11. Cliffs Of Dooneen – Christy Moore
  12. This song has been in my head for as long as I can remember hearing music. I think this was the first song that made me fall in love with what a minor chord can do. It was only years later when I messed around with a guitar that I realised what a minor chord was. In the line “But of all the fine places that I’ve ever seen”, the word “seen” hits me every time I listen to the song.

  13. Don’t Give Up – Peter Gabriel and Kate Bush
  14. I could listen to Peter Gabriel sing ingredients off the back of a cereal box, but this song stands out as something special even by his standards. I kind of forget sometimes that Kate Bush is no slouch as regards vocals, but for me every word Peter Gabriel sings on this is suberb. There are two moments that stand out for me. About 2mins 49secs in, just after Bush sings “there’s a place where we belong”, there are two notes on the Piano that mark a transition in the song and to my uneducated ear it’s magic. So simple, yet it almost turns into a different song. The other stand out moment is at about 3:25 when Gabriel sings “Got to walk out of here”. Love that voice.

    OK, that’s a few I have lots more, maybe I’ll add them in another post.

C# to F# Interop – Sharing a Domain Model

This entry is part 4 of 11 in the series Learning to think Functionally
Download
One of the first things I wanted to do with F# was call it from C#. I wanted to be able to take collections of domain objects written in C# and use F# goodness to process them.

It’s actually reasonably easy to do as you’d imagine for two .Net languages. There are one or two speedbumps, we’ll cover those here.

The Assemblies
The attached sample solution includes three projects, a Console Application written in C#, a Domain Model DLL containing two very simple classes, also written in C#, and a Library written in F#. Both the Console App and the F# Library reference the Domain Model, so both are aware of the Domain Objects, and these can be passed between the App and the Library. The Console app also references the F# library, so that it can use its functions.

I don’t know if it’s a problem with Visual Studio (2010) or a problem with me, but to reference the F# library from the C# app, I needed to browse to the DLL. A simple project reference seemed to cause errors.

The Domain Model
The domain model is simply a Product, and a Transaction. A Transaction represents the sale of a Product.

namespace DomainModel
{
    public class Product
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public long Price { get; set; }
    }

    public class Transaction
    {
        public long Id { get; set; }
        public Product Product { get; set; }
        public long quantity { get; set; }
    }
}

The Application is a Console App that creates a list of Transactions and passes it to functions in the F# library, and displays the results.

    class Program
    {
        static void Main(string[] args)
        {
            var transactions = GetTransactions();

            Console.WriteLine("PRODUCTS SOLD");
            var productsSold = Transactions.Stats.ProductsSold(transactions);
            foreach (var product in productsSold)
                Console.WriteLine(string.Format(product.Name));
            Console.WriteLine();

            Console.WriteLine("TOTAL REVENUE PER PRODUCT");
            var totalRevenuePerProduct = Transactions.Stats.TotalRevenuePerProduct(transactions);
            foreach (var productRevenueSummary in totalRevenuePerProduct)
                Console.WriteLine(string.Format("{0} : {1}", productRevenueSummary.Item1.Name, productRevenueSummary.Item2));
            Console.WriteLine();

            Console.WriteLine("TOTAL REVENUE");
            var totalCost = Transactions.Stats.TotalRevenue(transactions);
            Console.WriteLine(totalCost);
            Console.WriteLine();
        }

        private static IEnumerable<Transaction> GetTransactions()
        {
            var banana = new Product {Id = 1, Name = "Banana", Price = 2};
            var apple = new Product {Id = 2, Name = "Apple", Price = 1};
            var pear = new Product {Id = 3, Name = "Pear", Price = 3};

            var transaction1 = new Transaction {Id = 1, Product = banana, quantity = 5};
            var transaction2 = new Transaction {Id = 2, Product = apple, quantity = 10};
            var transaction3 = new Transaction {Id = 3, Product = pear, quantity = 6};
            var transaction4 = new Transaction {Id = 4, Product = apple, quantity = 5};
            var transaction5 = new Transaction {Id = 5, Product = pear, quantity = 7};
            var transaction6 = new Transaction {Id = 6, Product = pear, quantity = 8};
            var transaction7 = new Transaction {Id = 7, Product = apple, quantity = 4};

            return new List<Transaction>
                                   {
                                       transaction1,
                                       transaction2,
                                       transaction3,
                                       transaction4,
                                       transaction5,
                                       transaction6,
                                       transaction7
                                   };
        }
    }

Running the app, shows a distinct list of the products sold, the total sales revenue for each product, and an overall total revenue figures.

PRODUCTS SOLD
Banana
Apple
Pear

TOTAL REVENUE PER PRODUCT
Banana : 10
Apple : 19
Pear : 63

TOTAL REVENUE
92

There’s nothing Earth shattering here. You don’t need to use F# to get any of these figures. The point of this exercise is simply to demonstrate HOW to use F# to process your C# Domain Objects. You can figure out yourself WHEN it’s appropriate.

The F# Library

The F# library defines a namespace ‘Transactions’, and within that a module ‘Stats’. We open the DomainModel to get access to the Transaction and Product classes.

namespace Transactions

module Stats =

    open DomainModel

    let Revenue (t : Transaction) = 
        t.quantity * t.Product.Price

    let TotalRevenue (s : seq<Transaction>) = 
        s |> Seq.sumBy Revenue

    let TotalRevenuePerProduct (s : seq<Transaction>) =
        s |> Seq.groupBy(fun t -> t.Product)
          |> Seq.map (fun (key, values) -> (key, values |> TotalRevenue))

    let ProductsSold (s : seq<Transaction>) =
        s |> Seq.groupBy(fun t -> t.Product)
          |> Seq.map (fun (key, values) -> key)

I’ll take each of the functions in turn.

    let Revenue (t : Transaction) = 
        t.quantity * t.Product.Price

This simple little function calculates the revenue for an individual Transaction. Because we’re accessing properties, it’s important to specify the type. This function doesn’t get called directly from out C# code (although there’s no reason why it couldn’t be), it’s used by the TotalRevenue function.

    let TotalRevenue (s : seq<Transaction>) = 
        s |> Seq.sumBy Revenue

TotalRevenue is called from our C# app. Again, we use a type annotation to indicate that we’ll be receiving a Sequence of Transactions. Sequences are compatible with IEnumerable, so as long as our C# app is sending an IEnumerable this function will be able to work with the items. In the C# app we have a List which is of course compatible with IEnumerable.

The TotalRevenue function itself is very simple, it leverages the Revenue function described above to calculate the revenue for each Transaction. So, the TotalRevenue function really does exactly what it says on the tin. It sums the revenue for the Transactions. This highlights something that you should keep in mind when coding in F# (or indeed any language), it rarely hurts to break out a small specific piece of functionality and put it in it’s own function. It’s particularly true in Functional languages.

Breaking down the Revenue by product is a little trickier, but still pretty straightforward.

    let TotalRevenuePerProduct (s : seq<Transaction>) =
        s |> Seq.groupBy(fun t -> t.Product)
          |> Seq.map (fun (key, values) -> (key, values |> TotalRevenue))

Again we use a type annotation to indicate that the function receives a Sequence of Transactions. Our goal here is to return a sequence of tuples where the first value in the tuple is the Product, not just the name of the product, but the whole thing. The second item in the tuple will be a number indicating the total revenue for that product.

To produce the desired results we first group by the Product, we then take the Transactions grouped under each product and get the Total Revenue for that particular subset of Transactions.

The groupBy function takes a function that returns the key that we want to group by. The code here uses ‘fun t -> t.Product’ which means that for a Transaction t we take the product. The result of Seq.groupBy is a Sequence of tuples in which the first item is the key (the Product) and the second item is a Sequence containing the Transactions for that product.

Because the second item in the tuple is a Sequence of Transactions, it’s valid input for our TotalRevenue Function. It’s worth deconstructing the line of code that actually creates the sequence that we’re ultimately interested in.

Seq.map (fun (key, values) -> (key, values |> TotalRevenue))

It’s Seq.map which means it takes a sequence at applies the specific function to each item. In this case each item is a Tuple, so we assign the name ‘key’ to the first item in the tuple, and the name ‘values’ to the second item, which is itself a Sequence of Transactions. The function creates a tuple as it’s output, the first item of the output Tuple is ‘key’, which means it will be the Product.

The second item of the tuple shows ‘values’ being piped to TotalRevenue, which will return a number indicating the Total Revenue.

If you can get your head around the groupBy example above then you will have no problem with the final example.

    let ProductsSold (s : seq<Transaction>) =
        s |> Seq.groupBy(fun t -> t.Product)
          |> Seq.map (fun (key, values) -> key)

Again we use Type annotations, again we group by Product. This time we just want a distinct list of the Products that were sold. Out Seq.map function works like it did in the last example, except that instead of mapping to a tuple, we map to one value, which is the groupBy key, i.e. Product.

Learning to think functionally – Unfolding Sequences

This entry is part 2 of 11 in the series Learning to think Functionally

In my last post I worked through an example that finds the range of numbers that sum to a target value, or gets as close as possible without exceeding the target. I mentioned that the solution felt a little too like the loopy code I would have written in non-functional languages. I felt that there might be a more “functional” way of solving the problem, but I didn’t know what it was.

Ross McKinlay kindly added a comment to point out how the problem could be solved using the ‘unfold’ feature of sequences. When I first looked at the example, I felt like I often do when I see unfamiliar F# code. Utterly confused.

I eventually figured it out and thought it might be worth a further post. Let’s go back to where we left the code at the end of the last post.

let rec DoSumTo t currentNum currentSum =
    let nextNum = currentNum + 1
    match currentSum + nextNum > t with
    | false -> DoSumTo t nextNum (currentSum + nextNum)
    | true -> [1..currentNum]

let SumTo target =
    DoSumTo target 1 1

> SumTo 28;;
val it : int list = [1; 2; 3; 4; 5; 6; 7]

Let me say at the start, there’s a bug in this code. If you try SumTo 0, you get a wrong answer. We’ll address that bug in this post.

Here’s the alternative “unfold” solution that Ross provided.

let sumTo target =
    Seq.unfold(function
    | (current,total) when total >= target -> None
    | (current,total) -> Some(current,(current+1,total+current))) (1,0) 

Ross’ code has some issues too. For example…

> sumTo 2 |> ToList;;
val it : int list = [1; 2]

In this case the function returns a list of numbers that sum to more than the target. No biggie, a misplaced ‘=’, an easy fix. That aside, I really like the Seq.unfold feature. So, let’s step back for a second and explain some terminology, then we’ll continue.

The following is a very quick, incomplete, and probably inaccurate description of Ranges, Lists and Sequences. It will be just enough to allow you to understand the rest of the post, but I’d urge you to read up on these things yourself for a fuller picture.

Range
A Range Expression is simply a notation for defining a series of numbers from a low value to a high value. By default the increment is 1, but the Range notation also allows us to define a step size. For the purpose of this blog post we’re interested in using Range expressions to define the contents of Lists and Sequences.

List
A List is an ordered series of elements. Lists are immutable, and finite. To put it bluntly, lists actually contain stuff. All the elements in a list will be of the same type, but that can be pretty much anything. Numbers, words, tuples, types, or even other lists.

There are numerous ways of specifying the contents of a list. You can explicitly say what it contains…

let explicitList = [ 1; 2; 3 ]

You can also use a Range expression to define the contents of a list.

let rangeList = [ 1 .. 10 ]

If you want to change the increment size you can. The following range runs from 0 to 100 in steps of 5.

let skipList = [ 0..5..100 ]

Sequences
A Sequence is similar to a list. We can enumerate the items in the sequence, apply aggregate functions, etc. Sequences can be created using Range Expressions in much the same way that Lists can.

let rangeSequence = {1..10}

Note, that the only difference from Lists is that we use braces {} instead of the square brackets [].

The killer feature of Sequence is that the terms of the sequence are generated on an “as needed” basis. So, if a sequence defines a potential range of 1,000,000 items, but a particular function only accesses the first 10 terms, then only the 10 terms are generated. This allows for potentially infinite sequences.

Unfolding Sequences
And, with that very quick primer, we go back to the code from Ross and another much more interesting way to generate a Sequence, Unfolding.

Unfolding a sequence is actually a very simple notion. We use a function to generate the next term in the sequence based on the current term. An example is worth a thousand words, so let’s have one.

let TwoAtATimeFrom n =
    n
    |> Seq.unfold(function x -> Some(x, x+2))

val TwoAtATimeFrom : int -> seq<int>

> TwoAtATimeFrom 11;;
val it : seq<int> = seq [11; 13; 15; 17; ...]

The function accepts a number and pipes it into our unfold function. This value n is used only as the starting point for the sequence. Every subsequent term is calculated based on the previous term.

The key line of code is the unfold function, highlighted above. The result of this line of code is a sequence that starts at 11 (the value of n), and increases in steps of 2. But how? Let’s tear it apart.

It’s the ‘unfold’ method from the Seq module, so this bit is obvious enough.

Seq.unfold(...)

The interesting stuff is what goes on between those parenthesis.

function x -> Some(x, x+2)

We pass a function to unfold that accepts a number and generates the next number. To do that you might think (as I did) that it would be a simple function along the lines of

function x -> x + 2

But, the function actually contains ‘Some(x, x+2)’.
Why the ‘Some’ why both x and x + 2?

As with all things, it’s simple when you understand it, and it’s difficult until then.

‘Some’ indicates that we’re generating an Option value. By this I mean an item that may have a value, or may have none. In C# we’d call these Nullable. As long as the function produces some value the unfolding will continue. If it produces a ‘None’ value, the unfolding stops. Since the example above never produces a ‘None’ value, it is an infinite sequence.

Let’s modify it so there’s an upper limit of 1000.

let TwoAtATimeFrom n =
    n |> Seq.unfold(function 
    | x when x > 1000 -> None 
    | x -> Some(x, x+2))

We start with the value n, but now our unfold function has two options when generating the next term. If the term is greater than 1000, the function returns None, which stops the Sequence unfolding any further. As long as we’re less than 1000, new terms will be created.

Before we move on, let’s look at that “Some” syntax.

    x -> Some(x, x+2))

This says that as the sequence unfolds we take the value x (the first x), we add that value to the sequence (the second x) and then we generate the next value in the sequence by adding two to x (the x + 2). To really make this clear, lets generate another sequence.

let SeqFromTuple (x, y) =
    (x, y) |> Seq.unfold(function 
    (x, y) -> Some(y, (y, x+y)))

This function accepts a tuple, which is used as the starting value of the sequence that will be unfolded. As there is no provision to encounter a ‘None’ value this sequence has no set upper limit.

Each iteration creates a new tuple using the following transformation (x, y) -> (y, x+y). The following shows how that might look.

(1, 1) (1, 2) (2, 3), (3, 5), …

While these tuples are created, this does not reflect the actual sequence that is produced by the code. If you look at the first parameter of the ‘Some’, you’ll see it’s just ‘y’. So, while the unfold function produces a new tuple with each step, only the ‘y’ part of the tuple is actually realised into the Sequence. So the sequence actually looks like this.

> SeqFromTuple (1,1);;
val it : seq<int> = seq [1; 2; 3; 5; ...]

Before I finish let me return to the concept of Option types. These are used in situations where a value may or may not exist. An option will either have “Some” value or “None”. We’ve seen above how None can be used to flag the end of a process of unfolding a sequence. That’s not really a great example of the power of Option types.

Let’s go back to the exercise that started all of this. Given a number, find the range of numbers that sums to the target value. And recognising that not all values can be summed to exactly, we get as close as possible without exceeding the target.

Now, having learned about Option types we can improve this.

Given a number, find the range of digits that sum to the target number, and where no range sums exactly to the target, the function should indicate this by returning None.

Here’s the code.

let ThatSumClosestTo x =
    (0, 0)
    |> Seq.unfold(function 
        (total, num)-> if (total + num > x) 
                       then None 
                       else Some(num,(total + num, num + 1)))

let ThatSumsTo x =
    let closest = 
        ThatSumClosestTo x
        |> Seq.toList
    if closest |> List.sum = x 
    then Some(closest)
    else None

val ThatSumClosestTo : int -> seq<int>
val ThatSumsTo : int -> int list option

> 28 |> ThatSumsTo;;
val it : int list option = Some [0; 1; 2; 3; 4; 5; 6; 7]
> 29 |> ThatSumsTo;;
val it : int list option = None

Attempting to find a range of numbers, starting at 0 that sums to 28, gives 1 to 7, but for 29 there is no range of numbers that sums exactly, and so, the function indicates this by returning None.

I won’t go into detail about how this last version of the code works. I’ve presented enough explanation in this and previous posts for you to work it out, and it’s a worthwhile exercise. If you have any questions, feel free to leave a comment. If you can see opportunities to clean up the code, or simplify it, please leave a comment with suggestions.

Learning to think functionally: Iterating, Incrementing and Accumulating

This entry is part 1 of 11 in the series Learning to think Functionally

Another F# session this evening and some more deliberate practice of Functional Thinking. To be fair, this post isn’t really about anything new. If you’ve ever used recursion, even in non-functional languages, this will be old news. If you are new to Functional Programming and/or recursion then this may be useful.

Here’s a really simple function. It accepts a number n and sums all the numbers from 1 to n.

let SumUpToValue n = [1..n] |> List.sum

I create a range up to n and then it’s a simple matter to sum the numbers in the range.

What if I wanted to start from a target value, and work back to the range of numbers?

> SumTo 10;;
val it : int list = [1; 2; 3; 4]

Let’s agree one little ground rule here. Not every target number can be reached exactly by summing a range. Our function will get us as close as possible to the target without exceeding it.

If I was back in Imperativeland I’d create a loop starting from 1 and add to an accumulator until I reach the target. But here in Functionalville that’s apparently not how things are done. So, how are things done? How can I implement this function without iterating over a series of numbers, summing them, and using a loop guard so I know when to stop?

It turns out I can’t. That’s not to say it can’t be done, but the most “functional” solution I could come up with is basically the same solution as the loop described above, albeit with a cunning disguise.

Here was my first attempt

let rec DoSumTo t nums =
    let currentSum = List.sum nums
    let nextNumber = nums.Head + 1
    match currentSum + nextNumber > t with
    | true -> nums
    | false -> DoSumTo t (nextNumber::nums)

let SumTo target =
    DoSumTo target [1]


> SumTo 21;;
val it : int list = [6; 5; 4; 3; 2; 1]

‘DoSumTo’ is a recursive function that is passed the target value (t), and the list of numbers found so far (nums). The list of numbers provides us with two useful pieces of information. Adding one to the number at the head of he list gives us the next number that we need to add. So, the list is actually doubling up as the variable we would normally use as a loop counter.

Summing the contents of the list allows us to check if we’ve reached the target value yet, so the list is also doubling as the accumulator we would use if we were writing this using imperative code with mutable variables.

The function checks whether adding the next number to the list would cause us to exceed the target. If it would, we return the list as it currently stands, and that’s our answer. If adding the next number doesn’t exceed the target, the function recursively calls itself to try the next number.

The only reason I’m using pattern matching here rather than if..else is that as part of my practice I’m trying to avoid using If statements and While statements.

When ‘DoSumTo’ calls itself recursively it passes the target (t) unchanged, but it creates a new list consisting of the next number as the head, and the existing list of numbers as the tail. In other words, each new number is added at the head of the list.

This of course means that the resulting list of numbers is in reverse order. I don’t really care about this. The numbers are correct and reversing the list is trivial.

There is one potentially big problem with this code. Every call to ‘DoSumTo’ causes the list of numbers to be summed. That’s quite wasteful, and easily fixed. Let’s take another stab at this.

let rec DoSumTo t nums currentSum =
    let nextNumber = nums.Head + 1
    match currentSum + nextNumber > t with
    | false -> DoSumTo t (nextNumber::nums) (currentSum + nextNumber)
    | true -> nums

let SumTo target =
    DoSumTo target [1] 1

We’ve eliminated the summing of the whole list for each new number, by passing the currentSum as a parameter. Each run of the function increases the currentSum for the next run creating an accumulator.

We can go further. We don’t even need to pass the full list of numbers. The function uses the head of the list to keep track of what the next number should be, but we don’t use the full list until we’ve reached the target. Manipulating a full list when we don’t need to is wasteful.

let rec DoSumTo t currentNum currentSum =
    let nextNum = currentNum + 1
    match currentSum + nextNum > t with
    | false -> DoSumTo t nextNum (currentSum + nextNum)
    | true -> [1..currentNum]

let SumTo target =
    DoSumTo target 1 1

Now, instead of passing the full list, we just pass the number we’ve reached as we count up from 1. We also pass the target and the current sum of numbers up to that point. Now instead of using the head of the list of numbers, we just use currentNum.

The only other change is that when we reach the target number, we need to create a range for numbers from 1 to currentNum. This has the added bonus that the resulting list of numbers happens to be in the right order.

> SumTo 28;;
val it : int list = [1; 2; 3; 4; 5; 6; 7]