How to define and use% as a prefix operator?

type T() =
    static member (~%)(t : T) = t

let t = T()
let t' = %t // FAILS

The error message says it tshould have been of type Quotation.Expr<'a>. % is a presumably valid prefix operator , but can it actually be used?

+5
source share
2 answers

The reason you see this behavior is because F # does not define (~%)with static constraints, like most top-level operators. It is defined as a function Quotations.Expr<'a> -> 'a. Consequently, the function (~%)(which is an alias for op_Splice) that you have identified by type Tis not allowed using the top-level operator (~%).

FSI:

> <@ (~%) @>;;

  <@ (~%) @>;;
  ^^^^^^^^^^

C:\Users\Stephen\AppData\Local\Temp\stdin(5,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type
    val it : Expr<(Expr<'_a> -> '_a)>    
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.

, (~%) , :

let inline (~%) (x : ^a) = (^a : (static member op_Splice : ^a -> 'b) (x))

, :

let x = <@ 3 @>
<@ %x @>
----^
error FS0001: The type 'Expr<int>' does not support the operator '~%'

(~%) . , Expr Expr<'T>, - , op_Splice.

&& ||. ( op_BooleanAnd op_BooleanOr), , .

+5

, % , let:

let (~%) a = -a
%10

static ( , , - ), inline, . :

// Instead of defining static member '%', we define static member 'Percent'
type T() =     
    static member Percent(t : T) = t 

// Inline definition of '~%' that calls the static member 'Percent' of an object
let inline (~%) (x : ^T) = (^T : (static member Percent : ^T -> 'R) (x))  

// Now you can use the '%t' syntax to invoke the static member
let t = T()     
let t' = %t

: F # "" ( , , ). , .

let two = <@ 2 @>
let oneAndTwo = <@ 1 + %two @>
+4

All Articles