FLINQ and the Quotation Visualizer samples used this function but I cannot find it anywhere. Thanks.
The deepMacroExpandUntil function was quite a simple utility that only did two things:
It replaced all method calls with ReflectedDefinition attribute with the body of the method
It reduced lambda applications, so (fun x -> x * x) (1+2) would become (1+2)*(1+2)
This was quite useful when writing some quotation processing code, but newer versions of F# include ExprShape active patterns that make it quite easy to write quotation processing by hand.
To implement something like deepMacroExpandUntil, you would write something like:
open Microsoft.FSharp.Quotations
/// The parameter 'vars' is an immutable map that assigns expressions to variables
/// (as we recursively process the tree, we replace all known variables)
let rec expand vars expr =
// First recursively process & replace variables
let expanded =
match expr with
// If the variable has an assignment, then replace it with the expression
| ExprShape.ShapeVar v when Map.containsKey v vars -> vars.[v]
// Apply 'expand' recursively on all sub-expressions
| ExprShape.ShapeVar v -> Expr.Var v
| Patterns.Call(body, DerivedPatterns.MethodWithReflectedDefinition meth, args) ->
let this = match body with Some b -> Expr.Application(meth, b) | _ -> meth
let res = Expr.Applications(this, [ for a in args -> [a]])
expand vars res
| ExprShape.ShapeLambda(v, expr) ->
Expr.Lambda(v, expand vars expr)
| ExprShape.ShapeCombination(o, exprs) ->
ExprShape.RebuildShapeCombination(o, List.map (expand vars) exprs)
// After expanding, try reducing the expression - we can replace 'let'
// expressions and applications where the first argument is lambda
match expanded with
| Patterns.Application(ExprShape.ShapeLambda(v, body), assign)
| Patterns.Let(v, assign, body) ->
expand (Map.add v (expand vars assign) vars) body
| _ -> expanded
The following example shows both aspects of the function - it replaces the function foo with its body and then replaces the application, so you end up with (10 + 2) * (10 + 2):
[<ReflectedDefinition>]
let foo a = a * a
expand Map.empty <# foo (10 + 2) #>
EDIT: I also posted the sample to F# snippets.
Related
I have a custom variable definition, that I want to insert into a quotation. Is it even possible with the quotations syntax sugar?
What I wanted to do:
open Microsoft.FSharp.Quotations
let var = Var("myvar", typeof<int>)
let op = <## fun l -> match l with
| [] -> 0
| %%myvar :: _ -> ... ##>
I've also tried <## let %%myvar = ... ##> with a similar purpose.
In both cases I got FS0010 "Unexpected prefix operator in binding", or "... in pattern matching".
Is there a way to inject an existing Var like this? Or do I have to resort to manually generating the entire expression?
PS: I am using the whole thing to translate some other AST into an F# quotation.
What you describe in your question is really kind of nonsensical. You cannot splice a Var into an expression. Only a value of type Expr can be spliced. If you created an instance of Expr our of your var via the Expr.Var constructor, then the splicing would be possible:
let var = Expr.Var( Var("myvar", typeof<int>) )
let op = <## fun l -> %%var ##>
But this won't let you do what you're trying to do: you can't splice an expression in a pattern position (the left side of an arrow -> inside a match is what we call a "pattern", and so is the left side of equal sign = inside a let). You can only splice expressions, not other parts of the syntax. F# code quotations are not quite as free-for-all as Lisp macros or TemplateHaskell.
Admittedly, it is not entirely clear what you're actually trying to do.
One possibility of your true intent that comes to mind is this: you want to match this variable on the left side of the arrow ->, then pass it to some other function which would construct the right side of the arrow ->. Something like this:
let mkRightSide var = <## %%var + 42 ##>
let var = Expr.Var( Var("myvar", typeof<int>) )
let op = <## fun l -> match l with
| [] -> 0
| %%var :: _ -> %%(mkRightSide var) // Doesn't compile
##>
Which would yield the following quotation:
fun l -> match l with
| [] -> 0
| myvar :: _ -> myvar + 42
If this is your intent, then I suggest having mkRightSide return a function, which would simply take myvar as a parameter:
let mkRightSide = <## fun myvar -> myvar + 42 ##>
let op = <## fun l -> match l with
| [] -> 0
| (myvar:int) :: _ -> (%%mkRightSide) myvar ##>
The above would yield the following quotation:
fun l -> match l with
| [] -> 0
| myvar :: _ -> (fun myvar -> myvar + 42) myvar
Note 1: the type annotation on myvar is necessary because your quotations are untyped. Since mkRigthSide carries no type information, the compiler can't infer myvar to be int and makes it generic instead, which causes type mismatch when the splicing is attempted.
Note 2: the parentheses around (%%mkRightSide) are necessary. Without them, the compiler would understand it as %%(mkRightSide myvar), because function application has a higher priority than the %% operator.
If I am wrong in guessing your intent, please clarify it, and I'll be happy to amend the answer.
Excuse me if this is quite basic, I'm new to functional programming and F#.
I have to create a function that takes a list of tuples (string*int) and return a list of tuples (string *int)
So basically I want to apply some functions to each tuple in pairList and return a list of tuples.
I am guessing I could do this through a recursive function.
I have the following code so far:
let rec aFunction (pairList:List<string*int>): List<string*int> =
match pairList with
| [] -> []
| head :: tail -> [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))]
This basically just apply the various functions to only the head of the list and return me a list of tuple.
In order to get it working for the whole list I tried the following:
| head :: tail -> [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)));aFunction tail]
But I get the following error :
This expression was expected to have type string * int but here has type List < string * int >
This function does in fact exist already - it is called List.map.
To analyse your error, when you do [a;b] a and b need to have the same type.
What you wanted was to use the concatenation operator :: like this:
| head :: tail -> (fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))) :: (aFunction tail)
but you can actually make this neater by pattern matching in a better way
| (a,b) :: tail -> (a,snd (someFunc1 (someFunc2 (a,b)))) :: (aFunction tail)
John Palmers answer is more than good enough, but I would probably also go all the way and do about the following for clarity and readability:
let someFunc1 = id //just to make it compile
let someFunc2 = id //just to make it compile
let someFunc3 = someFunc2 >> someFunc1 >> snd
let someFunc4 head = fst head, someFunc3 head
let rec aFunction (pairList:List<string*int>): List<string*int> =
match pairList with
| [] -> []
| head :: tail -> someFunc4 head :: (aFunction tail)
And here's the List.map option John alluded to:
// make a helper function that converts a single tuple
let convertTuple (s, i) =
let i1 = (s, i) |> someFunc2 |> someFunc1 |> snd // pipeline operator helps remove parens
s, i1
// now you can simply
let aFunction pairList = List.map convertTuple pairList
// or even more simply using pointfree syntax:
let aFunction = List.map convertTuple
Note the above aFunction is so simple you may not even want a special function for it: it's perhaps more intuitive just to type out List.map convertTuple myList in full everywhere you need it.
That's the general idea with F#; start with some helpers that are the minimal transforms you want to make, and then build them up into bigger things using the combinators.
I have a discriminated union like this:
type A = |B | C of int*A
I have to pattern match like this (the parenthesis appear to be needed):
match x with
| B -> printfn "B"
| C (i,a) -> printfn "%A, %A" i a
Is there a way to instead match like this with something like an active pattern:
match x with
| B -> printfn "B"
| C i a -> printfn "%A, %A" i a
And if not how come F# is designed such that this matching with curried arguments doesn't work and it instead forces you to use a tuple?
Edit: This was inspired by the F# list in which you can use h::t without any tupling or anything like that. And the source code is like:
type List<'T> =
| ([]) : 'T list
| (::) : Head: 'T * Tail: 'T list -> 'T list
I think examining the definitions of a curried function and an active pattern will make this clear for you.
Curried function:
A function which takes multiple parameters but which allows you to pass them in one at a time in order to return a function which does the same thing but takes one fewer parameters. Example:
let add a b = a + b
//val add : a:int -> b:int -> int
let add5 = add 5
//val add5 : (int -> int)
Active Pattern:
A way of applying pattern matching where the matching can be done using parsing or other complex logic. Takes one parameter and returns the result of the parsing. So input -> single return parameter.
//Example taken from https://fsharpforfunandprofit.com/posts/convenience-active-patterns/
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true,int) -> Some(int)
| _ -> None
val ( |Int|_| ) : str:string -> int option
Since the whole point of currying a function is to be able to partially apply the function, the concept simply makes no sense when applied to the result of an active pattern.
Put another way, the result of an active pattern can't be "curried" because you can only curry functions and the result of an active pattern is data which is not a function. In your example, 'C (i,a)' is defining the return type of the Active Pattern case, not a function call.
You cannot have whitespace as delimiter between bound patterns, because neither union cases nor active patterns support this. Syntax as per the F# spec:
6.9.8 Evaluating Union Case
Case(e1,…,en)
7.2.3 Active Patterns
(|CaseName|) arg1 ... argn inp
(|CaseName|_|) arg1 ... argn inp
So it's necessarily one tupled argument for a union case; and n+1 arguments for the banana function, of which n arguments are parameters. Only the last argument binds to the pattern. Consider:
type X = B | C
let (|C|) a b = C (a, b)
let i = 42
match C with
| B -> printfn "B"
| C i a -> printfn "%A, %A" i a // prints 42, (42, C)
The case C in your discriminated union has a value of a tuple type (int * A).
The (i,a) part of your pattern matching isn't a parameter, it's matching the i to the int part and the a to the A part.
You could equally match with C x and x would hold a tuple of (int * A).
Myello! So I am looking for a concise, efficient an idiomatic way in F# to parse a file or a string. I have a strong preference to treat the input as a sequence of char (char seq). The idea is that every function is responsible to parse a piece of the input, return the converted text tupled with the unused input and be called by a higher level function that chains the unused input to the following functions and use the results to build a compound type. Every parsing function should therefore have a signature similar to this one: char seq -> char seq * 'a . If, for example, the function's responsibility is simply to extract the first word, then, one approach would be the following:
let parseFirstWord (text: char seq) =
let rec forTailRecursion t acc =
let c = Seq.head t
if c = '\n' then
(t, acc)
else
forTailRecursion (Seq.skip 1 t) (c::acc)
let rest, reversedWord = forTailRecursion text []
(rest, List.reverse reversedWord)
Now, of course the main problem with this approach is that it extracts the word in reverse order and so you have to reverse it. Its main advantages however are that is uses strictly functional features and proper tail recursion. One could avoid the reversing of the extracted value while losing tail recursion:
let rec parseFirstWord (text: char seq) =
let c = Seq.head t
if c = '\n' then
(t, [])
else
let rest, tail = parseFirstWord (Seq.skip 1 t)
(rest, (c::tail))
Or use a fast mutable data structure underneath instead of using purely functional features, such as:
let parseFirstWord (text: char seq) =
let rec forTailRecursion t queue =
let c = Seq.head t
if c = '\n' then
(t, queue)
else
forTailRecursion (Seq.skip 1 t) (queue.Enqueu(c))
forTailRecursion text (new Queue<char>())
I have no idea how to use OO concepts in F# mind you so corrections to the above code are welcome.
Being new to this language, I would like to be guided in terms of the usual compromises that an F# developer makes. Among the suggested approaches and your own, which should I consider more idiomatic and why? Also, in that particular case, how would you encapsulate the return value: char seq * char seq, char seq * char list or evenchar seq * Queue<char>? Or would you even consider char seq * String following a proper conversion?
I would definitely have a look at FSLex. FSYacc, FParsec. However if you just want to tokenize a seq<char> you can use a sequence expression to generate tokens in the right order. Reusing your idea of a recursive inner function, and combinining with a sequence expression, we can stay tail recursive like shown below, and avoid non-idiomatic tools like mutable data structures.
I changed the separator char for easy debugging and the signature of the function. This version produces a seq<string> (your tokens) as result, which is probably easier to consume than a tuple with the current token and the rest of the text. If you just want the first token, you can just take the head. Note that the sequence is generated 'on demand', i.e. the input is parsed only as tokens are consumed through the sequence. Should you need the remainder of the input text next to each token, you can yield a pair in loop instead, but I'm guessing the downstream consumer most likely wouldn't (furthermore, if the input text is itself a lazy sequence, possibly linked to a stream, we don't want to expose it as it should be iterated through only in one place).
let parse (text : char seq) =
let rec loop t acc =
seq {
if Seq.isEmpty t then yield acc
else
let c, rest = Seq.head t, Seq.skip 1 t
if c = ' ' then
yield acc
yield! loop rest ""
else yield! loop rest (acc + string c)
}
loop text ""
parse "The FOX is mine"
val it : seq<string> = seq ["The"; "FOX"; "is"; "mine"]
This is not the only 'idiomatic' way of doing this in F#. Every time we need to process a sequence, we can look at the functions made available in the Seq module. The most general of these is fold which iterates through a sequence once, accumulating a state at each element by running a given function. In the example below accumulate is such a function, that progressively builds the resulting sequence of tokens. Since Seq.fold doesn't run the accumulator function on an empty sequence, we need the last two lines to extract the last token from the function's internal accumulator.
This second implementation keeps the nice characteriestics of the first, i.e. tail recursion (inside the fold implementation, if I'm not mistaken) and processing of the input sequence on demand. It also happens to be shorter, albeit a bit less readable probably.
let parse2 (text : char seq) =
let accumulate (res, acc) c =
if c = ' ' then (Seq.append res (Seq.singleton acc), "")
else (res, acc + string c)
let (acc, last) = text |> Seq.fold accumulate (Seq.empty, "")
Seq.append acc (Seq.singleton last)
parse2 "The FOX is mine"
val it : seq<string> = seq ["The"; "FOX"; "is"; "mine"]
One way of lexing/parsing in a way truly unique to F# is by using active patterns. The following simplified example shows the general idea. It can process a calculation string of arbitrary length without producing a stack overflow.
let rec (|CharOf|_|) set = function
| c :: rest when Set.contains c set -> Some(c, rest)
| ' ' :: CharOf set (c, rest) -> Some(c, rest)
| _ -> None
let rec (|CharsOf|) set = function
| CharOf set (c, CharsOf set (cs, rest)) -> c::cs, rest
| rest -> [], rest
let (|StringOf|_|) set = function
| CharsOf set (_::_ as cs, rest) -> Some(System.String(Array.ofList cs), rest)
| _ -> None
type Token =
| Int of int
| Add | Sub | Mul | Div | Mod
| Unknown
let lex: string -> _ =
let digits = set ['0'..'9']
let ops = Set.ofSeq "+-*/%"
let rec lex chars =
seq { match chars with
| StringOf digits (s, rest) -> yield Int(int s); yield! lex rest
| CharOf ops (c, rest) ->
let op =
match c with
| '+' -> Add | '-' -> Sub | '*' -> Mul | '/' -> Div | '%' -> Mod
| _ -> failwith "invalid operator char"
yield op; yield! lex rest
| [] -> ()
| _ -> yield Unknown }
List.ofSeq >> lex
lex "1234 + 514 / 500"
// seq [Int 1234; Add; Int 514; Div; Int 500]
I've spent a few hours trying to get to grips with F# Quotations, but I've come across a bit of a road block. My requirement is to take simple functions (just integers,+,-,/,*) out of a discriminated union type and generate an expression tree that will eventually be used to generate C code. I know this is possible using Quotations with 'direct' functions.
My problem is that the expression tree seems to terminate with a "Value", and I can't figure out how to traverse into that value.
My questions is
whether this is actually possible in this situation? or are there any other approaches that are worth considering.
type FuncType =
| A of (int -> int -> int)
| B
| C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A (fun x y -> x + y )
let myFunc2 = A add
let thefunc expr =
match expr with
| A(x) ->
<# x #>
| _ ->
failwith "fail"
printfn "%A" (thefunc myFunc1) // prints "Value (<fun:myFunc1#14>)"
printfn "%A" (thefunc myFunc2) // prints "Value (<fun:myFunc2#15>)"
printfn "%A" <# fun x y -> x + y #> // generates usable expression tree
Quotations represent the F# code that was quoted syntactically. This means that if you write something like <# x #>, the quotation will contain just Value case specifying that you quoted something which has the specified value. (Variables are automatically replaced with values if the variable is defined outside of the quotation).
You can only get quotation of code that was explicitly quoted using <# .. #> or of a function that was marked as ReflectedDefinition and is referred to by name in a quotation (e.g. <# add #> but not for example let f = add in <# f #>).
To be able to do what your snippet suggests, you'll need to store quotations in your FuncType too (so that the lambda function that you write is also quoted and you can get its body). Something like:
type FuncType =
| A of Expr<int -> int -> int>
| B | C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A <# fun x y -> x + y #>
let myFunc2 = A <# add #>
let thefunc expr =
match expr with
| A(x) -> x
| _ -> failwith "fail"
This should work for functions marked as ReflectedDefinition too. To extract the body of the function you need to add something like (you'll need to substitute arguments of the function for parameters, but this should give you some idea):
match expr with
| Lambdas(_, body) ->
match body with
| Call(_, mi, _) when Expr.TryGetReflectedDefinition(mi) <> None ->
let func = Expr.TryGetReflectedDefinition(mi)
match func with
| Some(Lambdas(_, body)) ->
// 'body' is the quotation of the body
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported expression"