Skip to content

Instantly share code, notes, and snippets.

@dmitry-a-morozov
Created March 2, 2016 23:46
Show Gist options
  • Save dmitry-a-morozov/f6ca95f1af3ea144495b to your computer and use it in GitHub Desktop.
Save dmitry-a-morozov/f6ca95f1af3ea144495b to your computer and use it in GitHub Desktop.
Descriptive assertions using new F# 4.0 feature
open FSharp.Quotations
open System.Diagnostics
open System
type Debug with
[<Conditional("DEBUG")>]
static member AssertThat([<ReflectedDefinition(true)>] condition: Expr<bool>) =
match condition with
| Patterns.WithValue(value, t, expr) when t = typeof<bool> ->
let message = string expr //how do I get unparsed F# here?
Debug.Assert(unbox value, message)
| _ -> invalidArg "condition" (sprintf "Unexpected expressions: %A" condition)
Debug.AssertThat(42 = 42)
Debug.AssertThat(42 = 43)
@vladima
Copy link

vladima commented Mar 7, 2016

something like this (compile with --quotations-debug+):

open FSharp.Quotations
open System.Diagnostics
open System

module P = Patterns
module DP = DerivedPatterns

type Debug with
    [<Conditional("DEBUG")>]
    static member AssertThat([<ReflectedDefinition(true)>] condition: Expr<bool>) = 
        match condition with
        | P.WithValue(value, t, expr) when t = typeof<bool> -> 
            let text = 
                match expr.CustomAttributes with
                | [P.NewTuple([DP.String("DebugRange"); P.NewTuple([DP.String(file); DP.Int32(startLine); DP.Int32(startCol); DP.Int32(endLine); DP.Int32(endCol)])])] ->
                    failwith "TODO: read file and extract text between startline\\startcol and endline\\endcol"
                | _ -> string expr
            Debug.Assert(unbox value, text)
        | _ -> invalidArg "condition" (sprintf "Unexpected expressions: %A" condition)

Debug.AssertThat(42 = 42)
Debug.AssertThat(42 = 43)```

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