Skip to content

Instantly share code, notes, and snippets.

@eulerfx
eulerfx / IteratorInvariant.fs
Last active December 25, 2015 15:39
Iterator invariant with union type.
type 't Iterator = End | HasMoreElements of 't * 't Iterator
let rec print it =
match it with
| HasMoreElements (element,next) -> printfn "Element=%A" element ; print next
| End -> printfn "Finished!"
@eulerfx
eulerfx / ImmutableVo.fs
Created October 15, 2013 22:20
Immutable Money value object in F#
type Money = {
currency : string
amount : decimal
}
@eulerfx
eulerfx / ImmutableVo.cs
Created October 15, 2013 22:19
Immutable Money value object in C#
public class Money : IEquatable<Money>
{
public Money(string currency, decimal amount)
{
this.Currency = currency;
this.Amount = amount;
}
public string Currency { get; private set; }
public decimal Amount { get; private set; }
@eulerfx
eulerfx / AggregateWithValidation.fs
Last active December 16, 2015 18:29
Aggregate with explicit validation
module Aggregate
type Aggregate<'TState, 'TCommand, 'TEvent> = {
zero : 'TState;
apply : 'TState -> 'TEvent -> 'TState;
exec : 'TState -> 'TCommand -> Choice<'TEvent, string list>;
}
type Id = System.Guid
@eulerfx
eulerfx / InventoryItemApplicativeFunctorValidation.fs
Last active December 16, 2015 18:29
Inventory item validation with applicative functors.
open Validation
module private Assert =
let validName name = notNull ["The name must not be null."] name <* notEmptyString ["The name must not be empty."] name
let validCount count = validator (fun c -> c > 0) ["The item count must be positive."] count
let inactive state = validator (fun i -> i.isActive = false) ["The item is already deactivated."] state
let exec state =
function
| Create name -> Assert.validName name <?> Created(name)
@eulerfx
eulerfx / ApplicativeFunctorComposition.fs
Last active December 16, 2015 18:29
Applicative functor composition functions.
/// Lifts a two argument function to operate over the choice type.
let inline lift2 f a b = f <!> a <*> b
/// Composes two choice types, passing the case-1 type of the right value.
let inline ( *>) a b = lift2 (fun _ z -> z) a b
/// Composes two choice types, passing the case-2 type of the left value.
let inline ( <*) a b = lift2 (fun z _ -> z) a b
/// Composes a choice type with a non choice type.
@eulerfx
eulerfx / ApplicativeFunctorValidation.fs
Created April 28, 2013 18:53
Applicative functor validation composition primitives.
/// Given a value, creates a choice 1. (Applicative functor)
let puree = Choice1Of2
/// Given a function in a choice and a choice value x, applies the function to the value if available,
/// otherwise propagates the second choice. (Applicative functor)
let apply f x =
match f,x with
| Choice1Of2 f, Choice1Of2 x -> Choice1Of2 (f x)
| Choice2Of2 e, Choice1Of2 x -> Choice2Of2 e
| Choice1Of2 f, Choice2Of2 e -> Choice2Of2 e
@eulerfx
eulerfx / ValidatorBuilder.fs
Created April 28, 2013 18:21
Validator builder.
let validator predicate error x =
if predicate x then Choice1Of2 x
else Choice2Of2 error
@eulerfx
eulerfx / ChoiceValidation.fs
Created April 28, 2013 18:09
Validation with the Choice type.
let exec state =
function
| Create name ->
match name with
| null | "" -> Choice2Of2 ["The name must not be null or empty."]
| name -> Choice1Of2 (Created(name))
@eulerfx
eulerfx / ExceptionValidation.fs
Created April 28, 2013 17:51
Validation with exceptions
module private Assert =
let validName name = if System.String.IsNullOrEmpty(name) then invalidArg "name" "The name must not be null." else name
let validCount count = if count <= 0 then invalidArg "count" "Inventory count must be positive." else count
let inactive item = if item.isActive = true then failwith "The item is already deactivated."
let exec item =
let apply event =
let newItem = apply item event
event
function