Skip to content

Instantly share code, notes, and snippets.

@gusty
gusty / trampoline.fsx
Last active February 27, 2024 08:04
Trampolines in F#
let trampoline f c n =
let rec loop = function
| Choice1Of2 x -> x
| Choice2Of2 x -> loop (f x)
loop (Choice2Of2 (c,n))
// Test
let factorial n =
let rec factorialT (current, n) =
if n = bigint 0 then Choice1Of2 current
@gusty
gusty / polyvariadic.fsx
Last active July 20, 2023 15:19
Polyvariadic functions in F#
// Unfortunatelly it stopped working in F# 4.1 after this PR https://github.com/Microsoft/visualfsharp/pull/1650
// Will ask to revert it
type FoldArgs<'t> = FoldArgs of ('t -> 't -> 't)
let inline foldArgs f (x:'t) (y:'t) :'rest = (FoldArgs f $ Unchecked.defaultof<'rest>) x y
type FoldArgs<'t> with
static member inline ($) (FoldArgs f, _:'t-> 'rest) = fun (a:'t) -> f a >> foldArgs f
static member ($) (FoldArgs f, _:'t ) = f
@gusty
gusty / SixDependencyApproachesInPractice.fsx
Last active February 28, 2023 09:42 — forked from swlaschin/SixDependencyApproachesInPractice.fsx
Code examples from fsharpforfunandprofit.com/posts/dependencies-5/
(* ===================================
Code from my series of posts "Six approaches to dependency injection"
=================================== *)
open System
(*
## The requirements
@gusty
gusty / genericCDF.fsx
Last active November 17, 2022 05:15
Generic CDF
#r "nuget: FSharpPlus,1.2"
open FSharpPlus
open FSharpPlus.Math.Generic
type Ratio =
struct
val Numerator : bigint
val Denominator : bigint
new (numerator: bigint, denominator: bigint) = {Numerator = numerator; Denominator = denominator}
@gusty
gusty / memoization.fsx
Last active April 28, 2021 17:19
Polyvariadic Memoization
open System.Collections.Concurrent
type T = T with static member getOrAdd (cd:ConcurrentDictionary<_,'t>) (f:_ -> _) k = cd.GetOrAdd (k, f)
let inline memoize (f:'``(T1 -> T2 -> ... -> Tn)``): '``(T1 -> T2 -> ... -> Tn)`` = (T $ Unchecked.defaultof<'``(T1 -> T2 -> ... -> Tn)``>) f
type T with
static member ($) (_:obj, _: 'a -> 'b) = T.getOrAdd (ConcurrentDictionary ())
static member inline ($) (T, _:'t -> 'a -> 'b) = T.getOrAdd (ConcurrentDictionary ()) << (<<) memoize
@gusty
gusty / tuple.fsx
Last active March 26, 2021 10:10
Generic Tuple functions
// Based on http://nut-cracker.azurewebsites.net/blog/2011/11/07/functions-for-n-tuples/
// Warning: This script has long compile times
// but as from F# 4.1 will work fine
// due to this fix: https://github.com/Microsoft/visualfsharp/pull/1682 in the compiler
open System
type Infinite<'a> = Infinite of 'a
module TupleInternalValues =
+--------------------+--------------------+-------------------------+--------------------+
|Operation           | F#+ / F#           |F#+ Haskell Compatibility|Haskell             |
+====================+====================+=========================+====================+
|List.append         | @                  |                         | ++                 |
+--------------------+--------------------+-------------------------+--------------------+
|Function composition| f << g             | f . (g)                 | f . g              |
+--------------------+--------------------+-------------------------+--------------------+
|                    | <|                 | $                       | $                  |
+--------------------+--------------------+-------------------------+--------------------+
@gusty
gusty / curry.fsx
Created July 9, 2019 22:13
Polyvariadic curry / uncurry
#nowarn "0042"
let inline retype (x: 'T) : 'U = (# "" x: 'U #)
open System
type Curry =
static member inline Invoke f =
let inline call_2 (a: ^a, b: ^b) = ((^a or ^b) : (static member Curry: _*_ -> _) b, a)
call_2 (Unchecked.defaultof<Curry>, Unchecked.defaultof<'t>) (f: 't -> 'r) : 'args
@gusty
gusty / io-monad.fsx
Last active May 28, 2019 07:20 — forked from isaacabraham/io-monad.fsx
F# port of the first half of John De Goes "FP to the max" (https://www.youtube.com/watch?v=sxudIMiOo68)
#load @".paket\load\net452\FSharpPlus.fsx"
open FSharpPlus
open System
[<AutoOpen>]
module SideEffects =
let private r = Random()
let printLn text = async { printfn "%s" text }
let readLn() = async { return Console.ReadLine() }
@gusty
gusty / isNull.fsx
Created June 15, 2018 10:25
Efficiently constrained isNull
type A = class end
type B = class inherit A end
type C = class inherit B end
type D = class inherit C end
type IsNull =
inherit D
static member inline ($) (_:A , x :'a when 'a : not struct) = System.Object.ReferenceEquals(x, null)
static member inline ($) (_:B , x :'a when 'a : null ) = match x with null -> true | _ -> false
static member inline ($) (_:C , _:D) = false