Skip to content

Instantly share code, notes, and snippets.

@atsapura
Last active January 4, 2025 05:27
Show Gist options
  • Select an option

  • Save atsapura/fd9d7aa26e337eaa2f7f04d6cbb58ef6 to your computer and use it in GitHub Desktop.

Select an option

Save atsapura/fd9d7aa26e337eaa2f7f04d6cbb58ef6 to your computer and use it in GitHub Desktop.
type Test =
{ EntityId: string }
type Test2 =
{ EntityId: string
Name: string
Length: int }
let inline (|HasEntityId|) x =
fun () -> (^a : (member EntityId: string) x)
let inline entityId (HasEntityId f) = f()
let inline (|HasName|) n =
fun () -> (^a : (member Name: string) n)
let inline name (HasName f) = f()
let inline test2f (HasName n & HasEntityId id) = sprintf "name %s id %s" (n()) (id())
let test2 = {Test2.EntityId = "123"; Name = "123"; Length = 2}
let a = entityId { EntityId = "123" }
let b = entityId test2
let c = name test2
let d = test2f test2
@7c78
Copy link

7c78 commented Aug 1, 2019

How can I write like this? I want both generic and duck typing in the same function.

module T =
    let inline (|Id|) x =
        fun () -> (^a : (member Id: string) x)

    let inline id (Id f) = f()

    let inline test<'a> param =
        let aT = typeof<'a>.Name
        let idStr = id param
        sprintf "%s %s" aT idStr

    type C =
        { Name: string }
        with
        member __.Id = "1"

    let c = { Name = "abc" }

    let b = test<int> c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment