I'm want to create a method which would construct an equivalent of query { ... } computation expression (using FSharp.Data.TypeProviders with either LINQ2SQL or LINQ2Entities) from provided data structure, i.e.:
Collection("customers", [
Field "customerId";
Collection("orders", [
Field "orderId" ]) ])
For that I need to understand how the query is translated into code on the first place. Given following query as an example:
query {
for c in db.Customers do
select (c.CustomerID, query {
for o in c.Orders do
select o.OrderID
} |> Seq.toList)
}
What would it look like without computation expression syntax?
I would not recommend generating F# queries programmatically.
The main purpose of queries is to make it possible to write nicely looking F# source code. When they are executed, the code you write is first translated to LINQ-style expression tree, which is then translated to SQL query. If you managed to translate your query specification into F# query, you'd have something like:
+------------+ +----------+ +----------------------+ +-----+
| Your query | -> | F# query | -> | LINQ expression tree | -> | SQL |
+------------+ +----------+ +----------------------+ +-----+
There is nothing wrong with multiple transformations, but there is a number of things that make the path via F# query more complicated:
In your query format, things seem to be represented as strings. So, you'd need to go from strings to .NET MethodInfo just to go back to strings.
With F# queries/LINQ, you get back typed objects and that's one of the main benefits, but if you build query dynamically, you'll just get back a squence of obj values - and will have to use reflection or something like that to access them.
TL;DR - I think it will be much easier to just take your query representation and generate SQL directly. The structure of the transformation is similar to generating F# query, but you won't have to mess around with quotations and reflection.
If you want to see how something desugars, just put it into a quotation. If you do this with your example, you'll see that
<#
query {
for c in db.Customers do
select (c.CustomerID, query {
for o in c.Orders do
select o.OrderID
} |> Seq.toList)
}
#>
is roughly equivalent to
query.Run
<# query.Select(query.For(query.Source db.Customers,
fun c -> query.Yield c),
fun c ->
c.CustomerID,
query.Run <#
query.Select(query.For(query.Source c.Orders,
fun o -> query.Yield o),
fun o -> o.OrderID) #>
|> Seq.toList) #>
(where I've cleaned up a few extraneous variables). I agree with Tomas that there are probably better ways to achieve what you want than trying to create such an expression directly.
Related
I am trying to apply the free monad pattern as described in F# for fun and profit to implement data access (for Microsoft Azure Table Storage)
Example
Let's assume we have three database tables and three dao's Foo, Bar, Baz:
Foo Bar Baz
key | col key | col key | col
--------- --------- ---------
foo | 1 bar | 2 |
I want to select Foo with key="foo" and Bar with key="bar" to insert a Baz with key="baz" and col=3
Select<Foo> ("foo", fun foo -> Done foo)
>>= (fun foo -> Select<Bar> ("bar", fun bar -> Done bar)
>>= (fun bar -> Insert<Baz> ((Baz ("baz", foo.col + bar.col), fun () -> Done ()))))
Within the interpreter function
Select results in a function call that takes a key : string and returns an obj
Insert results in a function call that takes an obj and returns unit
Problem
I defined two operations Select and Insert in addition to Done to terminate the computation:
type StoreOp<'T> =
| Select of string * ('T -> StoreOp<'T>)
| Insert of 'T * (unit -> StoreOp<'T>)
| Done of 'T
In order to chain StoreOp's I am trying to implement the correct bind function:
let rec bindOp (f : 'T1 -> StoreOp<'T2>) (op : StoreOp<'T1>) : StoreOp<'T2> =
match op with
| Select (k, next) ->
Select (k, fun v -> bindOp f (next v))
| Insert (v, next) ->
Insert (v, fun () -> bindOp f (next ()))
| Done t ->
f t
let (>>=) = bindOp
However, the f# compiler correctly warns me that:
The type variable 'T1 has been constrained to be type 'T2
For this implementation of bindOp the type is fixed throughout the computation, so instead of:
Foo > Bar > unit
all I can express is:
Foo > Foo > Foo
How should I modify the definition of StoreOp and/or bindOp to work with different types throughout the computation?
As Fyodor mentioned in the comments, the problem is with the type declaration. If you wanted to make it compile at the price of sacrificing type safety, you could use obj in two places - this at least shows where the problem is:
type StoreOp<'T> =
| Select of string * (obj -> StoreOp<'T>)
| Insert of obj * (unit -> StoreOp<'T>)
| Done of 'T
I'm not entirely sure what the two operations are supposed to model - but I guess Select means you are reading something (with string key?) and Insert means that you are storing some value (and then continue with unit). So, here, the data you are storing/reading would be obj.
There are ways of making this type safe, but I think you'd get better answer if you explained what are you trying to achieve by using the monadic structure.
Without knowing more, I think using free monads will only make your code very messy and difficult to understand. F# is a functional-first language, which means that you can write data transformations in a nice functional style using immutable data types and use imperative programming to load your data and store your results. If you are working with table storage, why not just write the normal imperative code to read data from table storage, pass the results to a pure functional transformation and then store the results?
I am new in functional programming, I learn F# and sorry if question is stupid.
I want figure out with syntax and implement some simple data structure, but I don't know how do it.
How should look implementation of linked list?
I tried to create type, put there mutable property and define set of methods to work with the type, but it looks like object oriented linked list...
The basic list type in F# is already somewhat a linked list.
Though you can easily recreate a linked list with a simple union type:
type LinkedList<'t> = Node of 't * LinkedList<'t> | End
A node can have a value and a pointer to the next node or, be the end.
You can simply make a new list by hand:
Node(1, Node(2, Node(3, End))) //LinkedList<int> = Node (1,Node (2,Node (3,End)))
Or make a new linked list by feeding it an F# list:
let rec toLinkedList = function
| [] -> End
| x::xs -> Node (x, (toLinkedList xs))
Walking through it:
let rec walk = function
| End -> printfn "%s" "End"
| Node(value, list) -> printfn "%A" value; walk list
The same concepts would apply for a tree structure as well.
A tree would look something like
type Tree<'leaf,'node> =
| Leaf of 'leaf
| Node of 'node * Tree<'leaf,'node> list
The F# Wikibook has a good article on data structures in F#.
How can I write a no-op statement in F#?
Specifically, how can I improve the second clause of the following match statement:
match list with
| [] -> printfn "Empty!"
| _ -> ignore 0
Use unit for empty side effect:
match list with
| [] -> printfn "Empty!"
| _ -> ()
The answer from Stringer is, of course, correct. I thought it may be useful to clarify how this works, because "()" insn't really an empty statement or empty side effect...
In F#, every valid piece of code is an expression. Constructs like let and match consist of some keywords, patterns and several sub-expressions. The F# grammar for let and match looks like this:
<expr> ::= let <pattern> = <expr>
<expr>
::= match <expr> with
| <pat> -> <expr>
This means that the body of let or the body of clause of match must be some expression. It can be some function call such as ignore 0 or it can be some value - in your case it must be some expression of type unit, because printfn ".." is also of type unit.
The unit type is a type that has only one value, which is written as () (and it also means empty tuple with no elements). This is, indeed, somewhat similar to void in C# with the exception that void doesn't have any values.
BTW: The following code may look like a sequence of statements, but it is also an expression:
printf "Hello "
printf "world"
The F# compiler implicitly adds ; between the two lines and ; is a sequencing operator, which has the following structure: <expr>; <expr>. It requires that the first expression returns unit and returns the result of the second expression.
This is a bit surprising when you're coming from C# background, but it makes the langauge surprisingly elegant and consise. It doesn't limit you in any way - you can for example write:
if (a < 10 && (printfn "demo"; true)) then // ...
(This example isn't really useful - just a demonstration of the flexibility)
I'm working on a library to generate SQL from LINQ expressions (basically a modified subset of LINQ-to-SQL). I'm using discriminated unions to model the SQL expressions, but have encountered some (perceived?) limitations. I want to do something like the following (note the last line):
type SqlSourceExpression =
| Table of string
| Join of JoinType * SqlSourceExpression * SqlSourceExpression * SqlExpression //ie, left, right, predicate
and SqlExpression =
| Source of SqlSourceExpression
| OrderBy of SqlExpression * SortDirection
| Select of SqlSourceExpression * SqlExpression * OrderBy list //can't do this
I could do the following:
type SqlOrderByExpression = SqlExpression * SortDirection
...and change the last two lines to:
| OrderBy of SqlOrderByExpression
| Select of SqlSourceExpression * SqlExpression * SqlOrderByExpression list
But that appears to have two problems:
SqlOrderByExpression is not a SqlExpression. This makes it hard to use the visitor pattern (maybe herein lies the problem?). Which means when traversing a Select expression I can't iterate over the list of order by expressions passing each one to Visit(expr:SqlExpression).
SqlOrderByExpression is merely a type alias for a tuple, so no type information is preserved. That hurts readability IMO.
Is there a better way to model this? I tried the inheritance route, but I think DUs are MUCH easier to work with (barring the noted difficulty).
As you work with FP technique (DU), as you don't need to remember OOP patterns, just use high-order functions (fold, map, zippers, etc).
In case you just want to specific view for your matching code, there is active patterns:
let (|OrderByTerm|OrderByList|_|)= function
|OrderBy x -> Some (OrderByTerm x)
|Select (_,_,xs) -> Some (OrderByList xs)
|_ -> None
I'm not sure why SqlExpression, as a discriminated union, has cases for OrderBy and Select. What's allowed to go inside an OrderBy?
I think discriminated unions are making this more difficult than it needs to be. I think SqlSourceExpression, SqlOrderByExpression and SqlSelectExpression can be different types. You can make them records if you're worried about tuples being difficult to read (this is what I'd do in your situation).
I think an SqlExpression discriminated union will come in useful when you start to represent expression trees like (1 + SUM(ISNULL(Value1, Value2))) / COUNT(*), where the syntax is more flexible.
I'm trying to write a string processing function in F#, which looks like this:
let rec Process html =
match html with
| '-' :: '-' :: '>' :: tail -> ("→" |> List.of_seq) # Process tail
| head :: tail -> head :: Process tail
| [] -> []
My pattern matching expression against several elements is a bit ugly (the whole '-' :: '-' :: '>' thing). Is there any way to make it better? Also, is what I'm doing efficient if I were to process large texts? Or is there another way?
Clarification: what I mean is, e.g., being able to write something like this:
match html with
| "-->" :: tail ->
I agree with others that using a list of characters for doing serious string manipulation is probably not ideal. However, if you'd like to continue to use this approach, one way to get something close to what you're asking for is to define an active pattern. For instance:
let rec (|Prefix|_|) s l =
if s = "" then
Some(Prefix l)
else
match l with
| c::(Prefix (s.Substring(1)) xs) when c = s.[0] -> Some(Prefix xs)
| _ -> None
Then you can use it like:
let rec Process html =
match html with
| Prefix "-->" tail -> ("→" |> List.of_seq) # Process tail
| head :: tail -> head :: Process tail
| [] -> []
Is there any way to make it better?
Sure:
let process (s: string) = s.Replace("-->", "→")
Also, is what I'm doing efficient if I were to process large texts?
No, it is incredibly inefficient. Allocation and garbage collection is expensive and you're doing so for every single character.
Or is there another way?
Try the Replace member. If that doesn't work, try a regular expression. If that doesn't work, write a lexer (e.g. using fslex). Ultimately, what you want for efficiency is a state machine processing a stream of chars and outputting its result by mutating in-place.
I think you should avoid using list<char> and using strings and e.g. String.Replace, String.Contains, etc. System.String and System.StringBuilder will be much better for manipulating text than list<char>.
For simple problems, using String and StringBuilder directly as Brian mentioned is probably the best way. For more complicated problems, you may want to check out some sophisticated parsing library like FParsec for F#.
This question may be some help to give you ideas for another way of approaching your problem - using list<> to contain lines, but using String functions within each line.