Trouble with FSharp active patterns - f#

I'm parsing code quotations in FSharp and am building up pattern helpers. All was going well till I tried
let (|BinaryFn|_|) fn (input:Expr) =
function
| SpecificCall fn (_,_,l::r::[]) -> Some(l,r)
| _ -> None
let (|Multiply|_|) x =
function
| BinaryFn <# (*) #> (l,r) -> Some(l,r)
| _ -> None
The intention is to have a generic binary function matcher that returns the ''left'' and the ''right'' and then create specialised binary matchers such as Multiple, Divide and Add and Subtract.
However I get an error on the second pattern that
Error FS0001: Type mismatch. Expecting a
'a -> 'b option
but given a
'a -> 'c -> (Expr * Expr) option
The type ''a option' does not match the type
''b -> (Expr * Expr) option' (FS0001) (Shambolics)
Can somebody please enlighten me on what I should be doing here?

The issue here is that function doesn't only pattern-match the last argument, but also adds an additional argument (function is a combination between of fun and match). Remove the function argument input from the first pattern, and your problem will be solved.

Related

Matching tuple elements with "as" pattern

I'd like to convert tuple of two elements having the same type to a list. Code looks simple as this:
let toList (tuple: 'a * 'a): 'a list =
match tuple with
| (_ as fst, _ as snd) -> [fst; snd]
But somehow type of snd is 'a * 'a, so it seems like instead of binding second element of tuple to a variable the whole tuple is bound instead. Is it a bug in compiler or am I missing sth?
Actual code is more complicated, so the idea is not to rewrite the piece provided, but to understand what is wrong with the as usage here. I'd expect that as should go after the tuple to bound it as a whole, like this | (_ as fst, _ as snd) as tuple
For practical purposes #nilekirk's answer is better: you don't need as in this particular case at all.
But if you're wondering why snd has this type for learning purposes, here's an explanation.
Your pattern is compiled like this:
| ((_ as fst, _) as snd) ->
That is, tupling binds stronger than pattern aliasing.
If you want each as to apply to a single element of the tuple, you need to explicitly tell the compiler how to parenthesize them:
| ((_ as fst), (_ as snd)) ->
And incidentally, in F# tuples don't have to be in parens, so the outer parens are not necessary:
| (_ as fst), (_ as snd) ->
The correct syntactic form of the "as" pattern is
pat as ident
This defines ident to be equal to the pattern input and matches the pattern input
against pat.
For your code this means
let toList (tuple: 'a * 'a): 'a list =
match tuple with
| (fst, snd) -> [fst; snd]
where (fst, snd) is a tuple-pattern.
See F# language spec section 7.3 for full details of the "as" pattern.

F# matching expression and 'as' pattern

I'm studying some F# and trying to implement a parser combinator like in this tutorial; after some copy and paste of the proposed solution, I tried to customize it by myself.
Surely there's something I missed but the compiler gives me a weird error message.
type T<'a> =
| A of string
| B of 'a
let foo a b =
match a with
| A s as x -> x
| B i ->
match b with
| A s as x -> x
| B j ->
B (i, j)
The code above is a generalization of the issue I found: the error is notified in the last result (the B branch of the innermost matching expression):
error FS0001: Type mismatch. Expecting a
'a
but given a
'a * 'b
The resulting type would be infinite when unifying ''a' and ''a * 'b'
But if I don't use the as pattern:
let foo a b =
match a with
| A s -> A s // it can also be '| A s as x -> A s'
| B i ->
match b with
| A s -> A s
| B j ->
B (i, j)
then the compiler is happy again.
I don't get why I have to recreate the same logical result if it is already there.
In
A s as x -> x
x has type T<'a> while the required return type for foo is T<('a * 'a)>. Even though the A case does not contain any values of 'a it does not have a polymorphic type like forall 'a . T<'a>. In your second example you are creating a new instance of A which can have the required type.

How encode in a dictionary multiple functions of different types

I'm building a interpreter in F#. I'm trying to be clever and generalize the interpretation of primitive operators as function calls (in this case, as reductions).
This is the idea:
let reduce fx values =
Array.reduce values fx
let primitivesEnv =
let r = Dictionary<string,'T -> 'T -> 'T>()
r.["int_+"] <- reduce (fun(l:int, r:int) -> l + r)
r.["int_-"] <- reduce (fun(l:int, r:int) -> l - r)
r
So I could later do this:
env.["int_+"]([| 1, 2 |])
Of course, the type-checker reject this with
Warning FS0064: This construct causes code to be less generic than
indicated by the type annotations. The type variable 'T has been
constrained to be type ''a -> 'a -> 'a'. Error FS0001: Type mismatch.
Expecting a ('a -> 'a -> 'a) -> ('a -> 'a -> 'a) -> 'a -> 'a -> 'a
but given a ('a -> 'a -> 'a) -> 'a The resulting type would
be infinite when unifying ''a' and '('a -> 'a -> 'a) -> 'a -> 'a ->
'a'
P.D: I know how do this as a simple interpreter, but trying to build a solution that let me build dozens of methods in a generic way, without make a MATCH for each one.
First of all, there are some issues with your code. You have added a type annotation to your dictionary of 'T -> 'T -> 'T but it seems to me that it should return a function of type 'T[] -> 'T since you are trying to give it an array and evaluate a reduction.
Also, [| 1, 2 |] is an array of one tuple, you need an array of multiple values, such as this one : [| 1; 2 |]
I fixed your code like this:
let reduce values =
Array.reduce values
let primitivesEnv =
let r = System.Collections.Generic.Dictionary<string,'T[] ->'T>()
r.["int_+"] <- reduce ((+) : int -> int -> int)
r.["int_-"] <- reduce ((-) : int -> int -> int)
r
let result = primitivesEnv.["int_+"] [| 1; 2 |]
Unfortunately, this isn't the end of the problems.
We might have said that the dictionary is of type 'T[] ->'T but it isn't, the only valid type for the dictionary is int[] -> int, the first int -> int -> int type annotation creates that constraint. If we leave out that type annotation, 'T is constrained to int when we use it with an int[].
The type parameter 'T must always be resolved to a fixed type in some way, it isn't a wild card that lets you use anything.
This means that the dictionary approach is fine until you want to add float (or some other type) in addition to just int. Your only option, when using a dictionary, is to either choose one type or throw away some of your type-safety and resolve the specific type at runtime.
The simplest change to do that would be to create some union cases to describe the different reduction types:
type Reduction =
|IntReduction of (int[] -> int)
|FloatReduction of (float[] -> float)
You then create a Dictionary<string, Reduction> instead of a Dictionary<string,'T[] ->'T>.
When it comes to the more general problem of creating an interpreter in F#, I would start by creating a structured set of discriminated unions to describe the expressions and structure of the mini-language you wish to interpret, this is called an Abstract Syntax Tree (AST).
You can then define a run function that walks the tree and performs all the computations described by the AST.
I would also use a parser combinator library (I'd recommend FParsec) to parse whatever structured text into an abstract syntax tree of the union cases you defined in the step above.
Phillip Trelford has an example online of how to do this using FParsec for a simple C# AST: http://www.fssnip.net/lf This is probably far more powerful than what you need but hopefully it'll give you a starting point.

F# - Extract parameter from Expr

My questions will no end take...
I've the function:
let hasMany (expr:Expr<'a -> seq<'b>>)
now I want to extract the seq<'b> from the Expr since I need to cast it to an ICollection<'b> and wrap it back into a new Expr - Why not just make it take an Expr that takes an ICollection<'b> in the first place you may ask - simple enough the user would need to first cast the seq<'b> to an ICollection<'b>, which I'm trying to avoid since I'm creating a library thats going to be used by others than me, and I want it to be easy and clean.
Short: How do I extract the seq<'b>from the Expr?
Your question doesn't make sense to me. Given your types, there is no seq<'b> in expr - expr is an expression wrapping a function which returns a seq<'b>. For instance, with the signature you've got, it would be valid to call
hasMany <# id #>
since id can be given the type 'b seq -> 'b seq. However, clearly <# id #> doesn't contain a seq<'b>!
If what you're asking is to convert your Expr<'a -> seq<'b>> into an Expr<'a -> ICollection<'b>>, then try this:
let hasMany (expr : Expr<'a -> 'b seq>) =
<# fun x -> (%expr) x :?> ICollection<'b> #>

What is the difference between the `fun` and `function` keywords?

Sometimes I see code like
let (alt : recognizer -> recognizer -> recognizer) =
fun a b p -> union (a p) (b p)
Or like:
let hd = function
Cons(x,xf) -> x
| Nil -> raise Empty
What is the difference between fun and function?
The semantics for this is the same as in F# (probably because F# is based on OCaml):
function allows the use of pattern matching (i.e. |), but consequently it can be passed only one argument.
function p_1 -> exp_1 | … | p_n -> exp_n
is equivalent to
fun exp -> match exp with p_1 -> exp_1 | … | p_n -> exp_n
fun does not allow pattern matching, but can be passed multiple arguments, e.g.
fun x y -> x + y
When either of the two forms can be used, fun is generally preferred due to its compactness.
See also OCaml documentation on Functions.
The way I think about it
function patterns
is shorthand for
(fun x -> match x with patterns)
where 'patterns' is e.g.
| Some(x) -> yadda | None -> blah
(And
fun args -> expr
is how you define a lambda.)
Russ Cam is correct in his answer.
Here is a posting on the OCaml list talking about it
http://caml.inria.fr/pub/ml-archives/ocaml-beginners/2003/11/b8036b7a0c1d082111d7a83c8f6dbfbb.en.html
function only allows for one argument but allows for pattern matching, while fun is the more general and flexible way to define a function.
I generally use fun unless there is a good reason to use function.
You can see this in the code you posted where the fun declaration takes 3 arguments and the function declaration does pattern matching on it's input
fun x1 ... xn -> e
is an abbreviation for
function x1 -> ... -> function xn -> e

Resources