Skip to content

Instantly share code, notes, and snippets.

View TheAngryByrd's full-sized avatar
🐦
😠 🐦

Jimmy Byrd TheAngryByrd

🐦
😠 🐦
View GitHub Profile
@TheAngryByrd
TheAngryByrd / SemaphoreLock.fs
Created March 31, 2023 22:20
Disposable SemaphoreLock
open System
open System.Threading
open System.Threading.Tasks
// Based on https://gist.github.com/StephenCleary/7dd1c0fc2a6594ba0ed7fb7ad6b590d6
// and https://gist.github.com/brendankowitz/5949970076952746a083054559377e56
/// <summary>
/// An awaitable wrapper around a task whose result is disposable. The wrapper is not disposable, so this prevents usage errors like "use _lock = myAsync()" when the appropriate usage should be "use! _lock = myAsync())".
@TheAngryByrd
TheAngryByrd / SomeDIExample.fs
Created March 28, 2023 15:03
F# Dependency Injection
#r "nuget: Serilog, 2.9.0"
open System.Threading.Tasks
[<Interface>]
type ILogger =
abstract Debug: string -> unit
abstract Error: string -> unit
[<Interface>]
@TheAngryByrd
TheAngryByrd / BlockingObjectPool.fs
Created March 3, 2023 23:45
BlockingObjectPool
type BlockingObjectPool<'T when 'T : (new : unit -> 'T)>(maxCount : int) =
let pool = Stack<'T>(maxCount)
let semaphoreSlim = new SemaphoreSlim(maxCount, maxCount)
do for i=0 to maxCount do
let foo = new 'T()
pool.Push(foo)
member _.Get() =
printf $"Getting from pool : {semaphoreSlim.CurrentCount}"
semaphoreSlim.Wait()
@TheAngryByrd
TheAngryByrd / StubBuilderCE.fs
Last active April 24, 2025 14:03
Computation Expression Stub for F#
open System
// Replace with your type
type MyType<'a> = Async<'a>
type Internal<'a> = MyType<'a>
// Replace with types that feel similar and can be converted to `MyType`
type External1<'a> = System.Threading.Tasks.Task<'a>
type External2<'a> = System.Threading.Tasks.ValueTask<'a>
@TheAngryByrd
TheAngryByrd / SRTP-Active-Patterns.fs
Created October 11, 2022 23:08
SRTP-Active-Patterns.fs
module NameOps =
let inline (|HasName|) x = (^a : (member Name : string) x)
let inline (|HasAge|) x = (^a : (member Age : int) x)
let inline (|IsIdentifyable|) (HasName name & HasAge age) = name, age
let inline doWithIsIdentifyable (IsIdentifyable (name,age)) =
printfn $"{name} - {age}"
type Dog = {
Name : string
Age: int
@TheAngryByrd
TheAngryByrd / CurrentDirectory.fs
Created July 27, 2022 14:39
CurrentDirectory.fs
type CurrentDirectory = {
``System.AppContext.BaseDirectory`` : string
``AppDomain.CurrentDomain.BaseDirectory`` : string
/// Environment.CurrentDirectory is the same
``Directory.GetCurrentDirectory()`` : string
}
with
static member Create() =
{
``System.AppContext.BaseDirectory`` = System.AppContext.BaseDirectory
@TheAngryByrd
TheAngryByrd / program.fs
Last active April 14, 2022 04:29
F# MapGet helper
open System
open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.Hosting
open Microsoft.AspNetCore.Http
open System.Threading.Tasks
let mapGet (pattern : string) handler (app : WebApplication) =
app.MapGet(pattern, (Func<_>(handler))) |> ignore
let mapGetAsync (pattern : string) (handler : HttpContext -> Task) (app : WebApplication) =
@TheAngryByrd
TheAngryByrd / FSharpPlus.Then.fs
Last active March 28, 2022 14:36
FSharpPlus Then
type Default1 = class end
type Then =
inherit Default1
static member inline Then ((x: Result<_,'E> , f: 'T->Result<'U,'E>), _mthd: Then) = Result.bind f x
static member inline Then ((x: option<_> , f: 'T->Option<'U>), _mthd: Then) = Option.bind f x
static member inline Invoke (mapping: 'T->'U) (source: '``Thenable<'T>``) : '``Thenable<'U>`` =
let inline call (mthd: ^M, source: ^I, _output: ^R) = ((^M or ^I or ^R) : (static member Then : (_*_)*_ -> _) (source, mapping), mthd)
call (Unchecked.defaultof<Then>, source, Unchecked.defaultof<'``Thenable<'U>``>)
@TheAngryByrd
TheAngryByrd / OptionExtensions.fs
Created February 22, 2022 16:59
F# Option.Then
module Option =
let inline bind ([<InlineIfLambda>] binder) value =
match value with
| Some x -> binder x
| None -> None
let inline map ([<InlineIfLambda>] mapper) value =
match value with
| Some x -> Some(mapper x)
| None -> None
@TheAngryByrd
TheAngryByrd / GiraffeAsyncComposer.fs
Last active January 16, 2023 16:11
F# Giraffe Compose Async SRTP
open System
open Giraffe
open Microsoft.AspNetCore.Http
open System.Threading
open System.Threading.Tasks
module HttpHandlerHelpers=
/// Converts an Async HttpHandler to a normal Giraffe Task based HttpHandler
let inline convertAsyncToTask (asyncHandler : HttpFunc -> HttpContext -> Async<HttpContext option>) (next : HttpFunc) (ctx : HttpContext) : HttpFuncResult =