F# - Extract parameter from Expr - f#

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> #>

Related

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.

Does this pipe tuple operator already exist* somewhere?

I'm aware of (||>) which does (a' * 'b) -> ('a -> b' -> 'c) -> 'c
But I've been finding this quite useful, and wondered if I was reinventing the wheel:
// ('a * 'a) -> ('a -> 'b) -> ('b * 'b)
let inline (|>>) (a,b) f = (f a, f b)
(*It can happen, I only discovered the ceil function half an hour ago!)
No, it doesn't.
However, you will encounter its variant very often if you use FParsec. Here is the type signature in FParsec documentation:
val (|>>): Parser<'a,'u> -> ('a -> 'b) -> Parser<'b,'u>
I think the library has a very well-designed set of operators which can be generalized for other purposes as well. The list of FParsec operators can be found here.
I did a bit of digging; |>> operator doesn't seem to have built-in Haskell counterpart although it is easy to be defined using Control.Arrow.
The operator you described is essentially the map function for a two-element tuple. The map function, in general has a signature (for some F<'a> which could be seq<'a> or many other types in F# libraries):
map : ('a -> 'b) -> F<'a> -> F<'b>
So, if you define F<'a> as a two element tuple, then your function is actually just map (if you flip the arguments):
type F<'a> = 'a * 'a
let map f (a, b) = (f a, f b)
The operation is not built-in anywhere in the F# library, but it is useful to realize that it actually matches a pattern that is quite common in F# libraries elsewhere (list, seq, array, etc.)
Looking at the Haskell answer referenced by #pad - in principle, Haskell makes it possible to define the same function for all types that support such operations using type classes (so you would write just fmap instead of Seq.map or instead of your TwoElementTuple.map, but it actually does not work for various technical reasons - so Haskellers need to call it differently).
In F#, this is not easily possible to define a single map function for different types, but you can still think of your function as a map for two-element tuples (even if you find it easier to give it a symbolic operator name, rather than the name map.)

Parameterized Discriminated Union in F# [duplicate]

I am trying to write a typed abstract syntax tree datatype that can represent
function application.
So far I have
type Expr<'a> =
| Constant of 'a
| Application of Expr<'b -> 'a> * Expr<'b> // error: The type parameter 'b' is not defined
I don't think there is a way in F# to write something like 'for all b' on that last line - am I approaching this problem wrongly?
In general, the F# type system is not expressive enough to (directly) define a typed abstract syntax tree as the one in your example. This can be done using generalized algebraic data types (GADTs) which are not supported in F# (although they are available in Haskell and OCaml). It would be nice to have this in F#, but I think it makes the language a bit more complex.
Technically speaking, the compiler is complaining because the type variable 'b is not defined. But of course, if you define it, then you get type Expr<'a, 'b> which has a different meaning.
If you wanted to express this in F#, you'd have to use a workaround based on interfaces (an interface can have generic method, which give you a way to express constraint like exists 'b which you need here). This will probably get very ugly very soon, so I do not think it is a good approach, but it would look something like this:
// Represents an application that returns 'a but consists
// of an argument 'b and a function 'b -> 'a
type IApplication<'a> =
abstract Appl<'b> : Expr<'b -> 'a> * Expr<'b> -> unit
and Expr<'a> =
// Constant just stores a value...
| Constant of 'a
// An application is something that we can call with an
// implementation (handler). The function then calls the
// 'Appl' method of the handler we provide. As this method
// is generic, it will be called with an appropriate type
// argument 'b that represents the type of the argument.
| Application of (IApplication<'a> -> unit)
To represent an expression tree of (fun (n:int) -> string n) 42, you could write something like:
let expr =
Application(fun appl ->
appl.Appl(Constant(fun (n:int) -> string n),
Constant(42)))
A function to evaluate the expression can be written like this:
let rec eval<'T> : Expr<'T> -> 'T = function
| Constant(v) -> v // Just return the constant
| Application(f) ->
// We use a bit of dirty mutable state (to keep types simpler for now)
let res = ref None
// Call the function with a 'handler' that evaluates function application
f { new IApplication<'T> with
member x.Appl<'A>(efunc : Expr<'A -> 'T>, earg : Expr<'A>) =
// Here we get function 'efunc' and argument 'earg'
// The type 'A is the type of the argument (which can be
// anything, depending on the created AST)
let f = eval<'A -> 'T> efunc
let a = eval<'A> earg
res := Some <| (f a) }
res.Value.Value
As I said, this is a bit really extreme workaround, so I do not think it is a good idea to actually use it. I suppose the F# way of doing this would be to use untyped Expr type. Can you write a bit more about the overall goal of your project (perhaps there is another good approach)?

Typed abstract syntax tree with function application

I am trying to write a typed abstract syntax tree datatype that can represent
function application.
So far I have
type Expr<'a> =
| Constant of 'a
| Application of Expr<'b -> 'a> * Expr<'b> // error: The type parameter 'b' is not defined
I don't think there is a way in F# to write something like 'for all b' on that last line - am I approaching this problem wrongly?
In general, the F# type system is not expressive enough to (directly) define a typed abstract syntax tree as the one in your example. This can be done using generalized algebraic data types (GADTs) which are not supported in F# (although they are available in Haskell and OCaml). It would be nice to have this in F#, but I think it makes the language a bit more complex.
Technically speaking, the compiler is complaining because the type variable 'b is not defined. But of course, if you define it, then you get type Expr<'a, 'b> which has a different meaning.
If you wanted to express this in F#, you'd have to use a workaround based on interfaces (an interface can have generic method, which give you a way to express constraint like exists 'b which you need here). This will probably get very ugly very soon, so I do not think it is a good approach, but it would look something like this:
// Represents an application that returns 'a but consists
// of an argument 'b and a function 'b -> 'a
type IApplication<'a> =
abstract Appl<'b> : Expr<'b -> 'a> * Expr<'b> -> unit
and Expr<'a> =
// Constant just stores a value...
| Constant of 'a
// An application is something that we can call with an
// implementation (handler). The function then calls the
// 'Appl' method of the handler we provide. As this method
// is generic, it will be called with an appropriate type
// argument 'b that represents the type of the argument.
| Application of (IApplication<'a> -> unit)
To represent an expression tree of (fun (n:int) -> string n) 42, you could write something like:
let expr =
Application(fun appl ->
appl.Appl(Constant(fun (n:int) -> string n),
Constant(42)))
A function to evaluate the expression can be written like this:
let rec eval<'T> : Expr<'T> -> 'T = function
| Constant(v) -> v // Just return the constant
| Application(f) ->
// We use a bit of dirty mutable state (to keep types simpler for now)
let res = ref None
// Call the function with a 'handler' that evaluates function application
f { new IApplication<'T> with
member x.Appl<'A>(efunc : Expr<'A -> 'T>, earg : Expr<'A>) =
// Here we get function 'efunc' and argument 'earg'
// The type 'A is the type of the argument (which can be
// anything, depending on the created AST)
let f = eval<'A -> 'T> efunc
let a = eval<'A> earg
res := Some <| (f a) }
res.Value.Value
As I said, this is a bit really extreme workaround, so I do not think it is a good idea to actually use it. I suppose the F# way of doing this would be to use untyped Expr type. Can you write a bit more about the overall goal of your project (perhaps there is another good approach)?

F# - "Not a valid property expression"

I'm having this method which takes a Expr as parameter:
member x.HasSeq (expr:Expr<'a -> 'b seq>) =
let casted = <# fun z -> (%expr) z :?> ICollection<'b> #>
ManyNavPropertyInfo(cfg.HasMany <| toLinq casted)
What I want is to cast the 'b seq to an ICollection<'b>, which seems to work as it should, however when it reaches the line where it's going to convert the Expr to LINQ (need to do this since cfg.HasMany excepts a System.Expression<Func<'a,ICollection<'b>>>) it simply throws an exception saying:
InvalidOperationException:
The expression 'z =>
UnboxGeneric(ToFSharpFunc(z =>
z.Books).Invoke(z))' is not a valid
property expression. The expression
should represent a property: C#: 't =>
t.MyProperty' VB.Net: 'Function(t)
t.MyProperty'.
The function I use for converting Expr to LINQ:
let toLinq (exp : Expr<'a -> 'b>) =
let linq = exp.ToLinqExpression()
let call = linq :?> MethodCallExpression
let lambda = call.Arguments.[0] :?> LambdaExpression
Expression.Lambda<Func<'a, 'b>>(lambda.Body, lambda.Parameters)
I've used the toLinq function before without problems - I think it's because I cast b seq to ICollection<'b> which leaves UnboxGeneric in the Expr and when passing the Expr to toLinq it simply dosent know what to do with the UnboxGeneric - but of course thats just a theory, and I dont know what to do at all, in order to resolve it.
Your reasoning is correct - the problem is that the HasMany method recognizes only specific C# expression trees and the expression tree that your F# code generates is different.
My guess is that EF only handles a case when the expression tree is a plain access to a property of the right type - in the C# syntax something like: x => x.Foo (without any casting etc.). I think that the best option would be to modify your code to also expect a function 'a -> ICollection<'b>.
If you have some way for building a correct expression tree - e.g. if user specifies x => x.Foo, you want to return x => x.FooInternal, then you can use patterns & functions for working with F# quotations to rebuild the expression tree:
let hasSeq (e:Expr<'a -> seq<'b>>) =
match e with
| Patterns.Lambda(v, Patterns.PropertyGet(Some instance, propInfo, [])) ->
printfn "Get property %s of %A" propInfo.Name instance
// TODO: Use 'Expr.Lambda' & 'Expr.PropGet' to construct
// an expression tree in the expected format
| _ -> failwith "Not a lambda!"
... but keep in mind that the result needs to match the structure expected by HasMany. I guess that replacing the actual property specified by the user with some other property (e.g. some internal version that has the right type) is pretty much the only thing you can do.

Resources