Skip to content

Instantly share code, notes, and snippets.

@kspeakman
kspeakman / Ump.fs
Created October 27, 2022 00:45
Update Model Perform (UMP) -- MVU for back-end
namespace Utilities
(*
UMP (Update Model Perform) is a reformulation of MVU (Model View Update).
Here are the differences:
* `Cmd<Msg>` is replaced by a user-defined `Effect` (list) and a `perform` function
- allows testing that the correct side effects were chosen, using simple value equality (`=`)
- `Effect` is a DU, each case represents a side effect and its required data
- `perform` executes the `Effect`, returns a `Msg`
- without Cmd, all types are user-defined, so UMP code doesn't depend on UMP lib
@kspeakman
kspeakman / EventParser.fs
Last active September 8, 2022 19:19
Event parser
namespace Utilities
type EventType = string
type EventData = string
type EventParser<'union, 'meta> =
{
Deserializers : Map<EventType, EventData option -> Result<'union, exn>>
Serialize : 'union -> Result<EventType * EventData option, exn>
ParseMeta : string -> Result<'meta, exn>
@kspeakman
kspeakman / _README.md
Last active August 30, 2022 12:54
On Subscription IDs

Ref: elmish/elmish PR #248.

An early prototype of the "live subs" demo used the subscription settings + Msg type as the subscription ID. This worked as long as you only needed a single subscription. But it did not allow, for example, two timers on the same page with the same settings. That led me to switch to a user-provided Sub ID. This gives the user full control on when subscriptions are different or the same. It also gave ID the responsibility of triggering changes to a running subscription.

Subscriptions only have start/stop semantics. So "change" means stopping the running one and starting a new one with different settings. How ID controls this is illustrated in the live subs demo. Notice under Subscriptions -- which lists subscription IDs -- that the timer interval is part of the ID. When the user changes the interval from 1000 to 2000, the subscription ID goes from ".../interval/1000" to ".../interval/2000". T

@kspeakman
kspeakman / EmailerExample.fs
Last active December 2, 2021 02:36
UMP - MVU-style back end workflow
module Emailer
type Model =
{ SendLimitPerSecond: int
Today: DateTime
ToSend: Email list list }
type Effect =
| FindDueEmails of DateTime
| ScheduleSend of DateTimeOffset
@kspeakman
kspeakman / Main.fs
Last active March 31, 2021 23:11
ASP NET from F#
// F# type alias
type Builder = IApplicationBuilder -> IApplicationBuilder
let createWebServer settings =
let createBuilder () = (WebHostBuilder(), [])
let setConfig basePath (host: IWebHostBuilder, configs: Builder list) =
( host
.ConfigureAppConfiguration(fun (_: WebHostBuilderContext) (builder: IConfigurationBuilder) ->
@kspeakman
kspeakman / boot
Created October 2, 2020 13:00
meta-rpi-bt-dac 0.5.1 logs
Fri Mar 9 12:34:56 2018: Fri Mar 9 12:34:56 UTC 2018
Fri Mar 9 12:34:56 2018: urandom start: failed.
Fri Mar 9 12:34:56 2018: ALSA: Restoring mixer settings...
Fri Mar 9 12:34:57 2018: INIT: Entering runlevel: 5
Fri Mar 9 12:34:57 2018: Starting system message bus: dbus.
Fri Mar 9 12:34:57 2018: Starting bluetooth: bluetoothd.
Fri Mar 9 12:34:57 2018: Starting syslogd/klogd: done
Fri Mar 9 12:34:57 2018: bcm43xx_init
Fri Mar 9 12:34:57 2018: Flash firmware /lib/firmware/brcm/BCM43430A1.hcd
Fri Mar 9 12:35:02 2018: Set Controller UART speed to 921600 bit/s
@kspeakman
kspeakman / Ssm.fs
Last active December 13, 2018 23:43
Update-Perform style fetching parameters from AWS SSM
module Ssm
module GetParametersWorkflow =
open Amazon.SimpleSystemsManagement.Model
open System.Net
type Failure =
| ParameterRequestFailed of exn
| ParameterRequestError of HttpStatusCode * Amazon.Runtime.ResponseMetadata
@kspeakman
kspeakman / Async.fs
Created June 28, 2018 23:42
Helpers
namespace Utils
module Async =
let retn x =
async { return x }
let lift f =
f >> retn
@kspeakman
kspeakman / GuidBits.cs
Last active April 24, 2018 16:18
Utf8Json Short GUID parser
// differences from Utf8Json GuidBits
// * parses Base64 encoded Guids
// * writes Guids without '-' character
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct GuidBits
{
[FieldOffset(0)]
public readonly Guid Value;
@kspeakman
kspeakman / ListFolds.elm
Created February 14, 2018 21:51
Fixing Elm's List folds
module ListFolds exposing (..)
{-| Alternative implementations of List.foldl and List.foldr
-- this will add the `fold` and `foldBack` functions to the List module
import ListFolds as List
List.fold (++) "" [ "Hello", " ", "World", "!" ] == "Hello World!"
-}