Page 34 - MSDN Magazine, October 2019
P. 34

inheritance, you use a discriminated union to model the “is-a” relationship. Every time you create a new message type, you add it to the Message type.
You handle all messages: The update function is responsible for taking the current model and a single message, and giving back a new version of the model with any changes applied. Note that you don’t mutate the existing model; you copy and update the existing model with a new version, which fits perfectly with FP standard practice. You also use pattern matching to safely “unwrap” the message into the Increment message type.
You design your View: The view function takes in the current model, and creates some form of “view” that will be rendered to the screen. In this case, SAFE uses a sweet library that provides a strongly typed DSL over the React framework.
Let’s dig a little deeper into Elmish now, by taking note of some additional interesting things in the previous sample Elmish.
Strongly typed: As you can see in Figure 4, functions and types for React elements such as div and input, and events such as OnClick, are all strongly typed with full IntelliSense.
Lightweight syntax: F# can easily represent a hierarchical view of HTML-like elements. For example, F# has language support for lists—two bracket characters “\[ \]” represent a generic list of elements.
Handling user input: The use of the dispatch function allows you to send messages from the UI back into the update function, completing the MVU loop.
Using React: Aside from being a rock-solid and performant library created by Facebook, one of the reasons Elmish sits on top of React is that it provides a highly efficient “diff engine” that can rapidly compare two “virtual” views and update just the HTML elements that have been modified. It’s this diff engine that means Elmish can use immutable
Figure 5 Exhaustive Pattern Matching in Action
thing from the get-go, meaning much less time fighting in the
debugger later on.
Value Adds with SAFE
Now that you’ve seen the different components that make up the default SAFE stack, let’s look at some of the other benefits that might not be apparent yet.
Code sharing: Because Fable does such an excellent job writing JavaScript from F#, you can easily share code between client and server—from simple data types to entire modules and functions. For example, you can seamlessly share data contracts between client and server (rather than, for example, JSON or TS types and C# classes) and perform common validation on the client and server, as well as start to make more complex client applications without worrying about increased complexity.
Cloud support: The SAFE stack has great support for different cloud hosting providers. For example, on the Azure front there’s built-in support for Azure deployments through ARM templates,
models and views, but still have excellent performance.
A Word on Pattern
Matching
C# 8.0 has introduced a variant of pattern matching with switch expressions. It’s a pretty good implementation, although it doesn’t support one of the key features that F# discriminated unions give, called exhaustive matching. For example, if I were to define a new Decrement mes- sage to reduce the counter value, the compiler would immediately tell me where I needed to “fill in” the blanks until it was sure that I had accounted for all possible messages, as shown in Figure 5.
This kind of exhaustive match- ing is one of the reasons F# is such a fun and enjoyable experience— it really helps you to do the “right”
Figure 6 A Rich Data-Driven Application Using Azure Services
30 msdn magazine
F#












































































   32   33   34   35   36