Hacker News new | ask | show | jobs
by chriswarbo 4043 days ago
Really, the author is in favour of polynomial types (sums of products); the emphasis on sums is probably because tuples/records/arrays/etc. are already quite well known.

To see the distinction, notice that many Actions have some associated data:

    data Action a
      = ClearCompleted
      | DeleteItem ItemId
      | EditItem ItemId
      | EditItemCancel ItemId
      | EditItemDone ItemId a
      | Filter (Maybe ItemStatus)
      | NewItem a
      | NoAction
      | Refresh
      | Toggle ItemId
      | ToggleAll
In your analogy, the `action` value is actually quite complicated: it's an object (record) containing a field called "type" containing a string; if the "type" field contains the string "DeleteItem" then the action object also contains a "todo" field, containing an item ID; if the "type" field contains the string "EditItem" then the action object also contains a "todo" field, containing an item ID; and so on.

This is known as a "dependent record", and requires a much more elaborate type system than polymonial types. In fact, without careful consideration, dependent type checking can end up being undecidable!

Compare this to the polynomial type, where the parameters (item IDs, etc.) are right there in the value. We can never have an Action without the corresponding parameters (if we try, we'll end up with a function rather than an Action, thanks to Currying). We can never switch the type of an action while forgetting to change the parameters; etc. Plus, of course, we've denoted a finite set of actions, rather than relying on strings (AKA "stringly typed" programming).

Another point to note:

> it's simpler to directly call the right function, rather than over-engineering things with a short-lived intermediary representation.

Of course it would be simpler, but the entire point of the exercise is to use MVC to separate concerns, even though it's clearly overkill. If we're going to do MVC anyway, then the Action type provides a very simple interface between the Controller and the Model: the Controller just spits out an Action, the Model just receives an Action; no need for any further coordination. Plus, it's all really easy to reason about and type check.