Skip to content

Instantly share code, notes, and snippets.

@Savelenko
Savelenko / ExistentialEngines.fs
Last active March 26, 2024 11:27
F# existential types
// The engine interface and helpers
type IEngine<'a,'b> =
abstract member Capacity : int // Does not depend on 'a or 'b; just an example
// Some other stuff here possible depending on 'a and 'b
/// A function which works on any engine polymorphically and returns a result of type 'r'. Needed because
/// F# does not support higher-ranked types (not the same as HKT!) in regular functions. This does work in members.
type EngineFunction<'r> =
abstract member Apply : IEngine<'a,'b> -> 'r
@Savelenko
Savelenko / GADTMotivation.fs
Last active February 9, 2024 12:00
Motivated simulation of GADTs in F#, quite motivational
module GADTMotivation
(*
Here is a simple motivational example for GADTs and their usefulness for library design and domain modeling. Suppose we
need to work with settings which can be displayed and adjusted in a GUI. The set of possible setting "types" is fixed
and known in advance: integers, strings and booleans (check-boxes).
The GUI should show an example value for each possible setting type, e.g. 1337 for an integer setting and "Hello" for a
string setting. How can we model this small domain of setting types and computing example values?
*)
@Savelenko
Savelenko / Zipper.fs
Last active January 26, 2024 08:51
Family tree zipper example
module Zipper
type Person = { Name : string; Children : List<Person> }
type Parent = Parent of {| Name : string; OtherChildren : List<Person> |} // Note *other* children
/// The "family tree" zipper
type FamilyTree = FamilyTree of Person * List<Parent> // A person and his/her ancestors
/// Person -> FamilyTree
@Savelenko
Savelenko / EarlyReturnAsync.fs
Created September 29, 2023 10:42
Async with early return capability CE for F#
(* Library portion *)
/// Just like Async but supports early return with skipping the rest of computations.
type ContAsync<'r,'a> = ('a -> Async<'r>) -> Async<'r>
/// Early return.
let early (a : 'a) : ContAsync<'a,_> = fun _ -> async { return a }
/// Computation expression builder.
@Savelenko
Savelenko / EarlyReturnExperiment.fs
Created September 28, 2023 14:26
Early return computation expression in F#
(* An experiment with implementing early return in F#. Initial examples work, but I do not know whether it is really correct! *)
/// A computation which runs to completion and produces 'r or returns an 'a early, short-circuiting some steps.
type R<'a,'r> =
private
| Done of 'r
| EarlyReturn of 'a
| Zero
| Effect of (unit -> R<'a,'r>)
@Savelenko
Savelenko / RankNExample.fs
Created September 25, 2023 10:04
When a HOF breaks in F#
// A polymorphic function which works for values of *any* type.
let hello (a : 't) : string =
// Just ignore the argument
"Hello"
// We can use it any context, on any input: it is polymorphic after all.
let result =
let a = hello 1
let b = hello "string"
@Savelenko
Savelenko / FactoryDemo.fs
Created September 25, 2023 09:06
Polymorphic factory methods
type Factory<'T> = unit -> Option<'T>
type NoOptionFactory<'T> = unit -> 'T
type FactoryTests () =
member _.CanFactory () =
// Use the Option-returning factory
let factory : Factory<'T> = FactoryTests.FactoryFunction
let testString : Option<string> = factory ()
let testInt : Option<int> = factory ()
@Savelenko
Savelenko / Example.cs
Created September 7, 2023 09:15
LINQ-to-nothing-special
private static void Main(string[] args)
{
/* LINQ-to-nothing-special */
Just<int> five = 5;
Just<int> six = 6;
var eleven = from a in five
from b in six
select a + b;
@Savelenko
Savelenko / Mendler.fs
Created April 27, 2023 10:01
Pretty printing trees in F# using a Mendler-style catamorphism
/// Non-empty trees.
type Tree<'a> = TreeNode of 'a * List<Tree<'a>>
/// Syntactic simulation of the `Tree` base functor.
let (|TreeNode_|) (a, ys) = (a, ys)
/// Regular catamorphism for `Tree`.
let rec cata f (TreeNode (a, ts)) = f a (ts |> List.map (cata f))
/// Compute a result from a single `Tree` node while having access to a function which computes a result from a single
@Savelenko
Savelenko / MeetingLocation.fs
Last active March 17, 2023 09:13
Meetings and locations model using simulated GADTs in F#
module EmployeeLocation
open TypeEquality
type Name = string
/// Some employees are engineers.
type Engineer = Engineer of Name
/// Some employees are factory workers.