In F# I can create a sequence of 1 item by
seq [42] // inefficient, since a list is created
seq { yield 42} // verbose, would prefer { 42 } or seq { 42 }
seq { 42 .. 42 } // bizarre
While I find this a bit strange, I am curious if someone knows a short and efficient way.
Or: Why is
{ 42 } // invalid syntax. in other words, not a valid sequence expression
not valid?
You could use:
Seq.singleton 42
If you need a true sequence (i.e. an IEnumerable whose items are created lazily), the seq { yield <expr> } is probably the most concise syntax.
If you don't need the item to be evaluated only when it is consumed (eager evaluation is fine), then you can use the Seq.singleton function.
If you only need something that implements IEnumerable, you can achieve shorter syntax by using a list or an array constructor: [ <expr> ] or [| <expr> |], the difference being that array constructor will be probably more efficient in this case.
The { <expr> } syntax won't work because there is no such special syntax for creating a sequence (as, for example, a generator expression in Python). The seq { yield <stuff> } is a computation expression, and it has to follow several rules, one of which being that it has to say what kind of computation it defines (the seq part says that). If you wanted to omit the seq part, you'd need F# to support generic computation expressions, which I don't think is currently possible (and would probably require some capability similar to typeclasses).
Related
I'm new to F# and I've been struggling with this for a while. I have a two-dimensional array ([,]) and I want to get a sequence of all the elements in this array. While there seem to be options to iterate such an array (e.g. Array2D.iter), I want to pass the sequence to some other functions, not just iterate the elements.
In the end, I've worked around this with the following function:
let getAllElements (a: MyDiscriminatedUnionType[,]) : (seq<MyDiscriminatedUnionType>) =
seq { for x in a do yield (x :?> MyDiscriminatedUnionType) }
this seems to work but looks very excessive to me. Since the for .. in expression works on an enumerable-expression there already seems to be a way to enumerate a multidimensional array more easily?
Also I can't really figure out how to make this function more generic, so that this isn't tied to MyDiscriminatedUnionType but works with all multi-dimensional arrays.
To answer the second part of your question, you can make the function generic by replacing MyDiscriminatedUnionType type with a generic type parameter such as 'a:
let getAllElements (a:'a[,]) : seq<'a> =
seq { for x in a do yield x :?> 'a }
I think the code is quite clean - it would be nice if there was a built-in function for this (say, Array2D.toSeq) and I think it would be reasonable to suggest this as an addition to the standard F# library, but I don't think there is a function like this - and then the sequence expression is a nice way of writing this.
The only annoying thing is that you have to cast x using x :?> 'a. This is because the 2D array type does not implement a generic IEnumerable<'a> interface, but only the (old style) non-generic version.
You could avoid that by iterating over the indices and indexing into the array, which is a bit longer, but avoids the ugly casting:
let getAllElements (a:'a[,]) : seq<'a> =
seq { for i in 0 .. a.GetLength(0)-1 do
for j in 0 .. a.GetLength(1)-1 do yield a.[i,j] }
I'm trying to write a "toy" interpreter using Flex + Lemon that supports a very basic "let" syntax where a variable X is temporarily bound to an expression. For example, "letx 3 + 4 in x + 8" should evaluate to 15.
In essence, what I'd "like" the rule to say is:
expr(E) ::= LETX expr(N) IN expr(O). {
environment->X = N;
E = O;
}
But that won't work since O is evaluated before the X = N assignment is made.
I understand that the usual solution for this would be a mid-rule action. Lemon doesn't explicitly support this, but I've read elsewhere that would just be syntactic sugar in any event.
So I've tried to put together a mid-rule action that would do my assignment of X = N before interpreting O:
midruleaction ::= /* mid rule */. { environment->X = N; }
expr(E) ::= LETX expr(N) IN midruleaction expr(O). { E = O; }
But that won't work because there's no way for the midruleaction rule to access N, or at least none I can see in the lemon docs/examples.
I think I'm missing something here. I know I could build up a tree and then walk it in a second pass. And I might end up doing that, but I'd like to understand how to solve this more directly first.
Any suggestions?
It's really not a very scalable solution to evaluate immediately in a parser. See below.
It is true that mid-rule actions are (mostly) syntactic sugar. However, in most cases they are not syntactic sugar for "markers" (non-terminals with empty right-hand sides) but rather for non-terminals representing production prefixes. For example, you could write your letx rule like this:
expr(E) ::= letx_prefix IN expr(O). { E = O; }
letx_prefix ::= LETX expr(N). { environment->X = N; }
Or you could do this:
expr(E) ::= LETX assigned_expr IN expr(O). { E = O; }
assigned_expr ::= expr(N). { environment->X = N; }
The first one is the prefix desugaring; the second one is the one I'd use because I feel that it separates concerns better. The important point is that the environment->X = N; action requires access to the semantic values of the prefix of the RHS, so it must be part of a prefix rule (which includes at least the symbols whose semantic values are requires), rather than a marker, which has access to no semantic values at all.
Having said all that, immediate evaluation during parsing is a very limited strategy. It cannot cope with a large range of constructs which require deferred evaluation, such as loops and function definitions. It cannot cleanly cope with constructs which may suppress evaluation, such as conditionals and short-circuit operators. (These can be handled using MRAs and a stateful environment which contains an evaluation-suppressed flag, but that's very ugly.)
Another problem is that syntactically incorrect expressions may be partially evaluated before the syntax error is discovered, and it may not be immediately obvious to the user which parts of the expression have and have not been evaluated.
On the whole, you're better off building an easily-evaluated AST during the parse, and evaluating the AST when the parse successfully completes.
I am looking at the following F# line
for i = 0 to i=10 do
Console.WriteLine("Hello")
An I am wondering that isn't the above line a statement as opposed to an expression?
Shouldn't everything be an expression in F#?
As already said, every syntactical construct in F# is an expression. F# does not distinguish between statements and expressions (and so I'd say that the WikiPedia quote posted by Robert is a bit misleading - F# does not have statements).
Actually, the above is not fully true, because some constructs in F# computation expressions such as let! are not expressions, but we can ignore that.
What does that mean? In C#, the syntax of for and method calls is defined something like this:
statement := foreach(var v in <expression>) <statement>
| { <statement> ... <statement> }
| <expression>;
| (...)
expression := <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
This is very simplified, but it should give you the idea - a statement is something that does not evaluate to a value. It can be foreach loop (other loops), a statement block (with multiple statements) or an expression with semicolon (where the result of the expression is void or is ignored). An expression is, for example, method call, primitive literal (string, int) or a binary operator.
This means that you cannot write certain things in C# - for example, the argument of method call cannot be a statement (because statements do not evaluate to a value!)
On the other hand, in F#, everything is an expression. This means there is just a single syntactic category:
expression := for v in <expression> do <expression>
| <expression>; <expression>
| <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
This means that in F# all syntactic constructs are expressions, including for and other loops. The body of for is also an expression, but it would not make sense if the expression evaluated to some value (i.e. 42), so the types require that the result of the body is unit (which does not carry any information). Similarly, the first expression in sequencing (<expr>; <expr>) should return unit - the result of sequencing is the result of the second expression.
This makes the language simpler and more uniform, but you can write some odd things:
let x = (for i in 0 .. 10 do printfn "%d" i); 42
This will print numbers from 0 to 10 and then define a value x to be 42. The assignment is a sequencing of expressions (<expr>; <expr>) where the first one is for loop (that has a type unit, because it does not evaluate to anything) and the second one is 42, which evaluates to 42.
Every statement in F#, including if statements and loops, is a
composable expression with a definite return type.
Functions and expressions that do not return any value have a return
type of unit.
http://en.wikipedia.org/wiki/F_Sharp_(programming_language)
In languages like F# statements are just expressions that return the value () of type unit. As the unit type has only one value it conveys no information so returning the value of type unit is saying "if I'm doing anything then it is by way of a side effect" like printing to the console or writing to disk.
Note that not everything is an expression in F#. Type definitions are not expressions. Patterns are not expressions. And so on...
I only know F#. I haven't learned the other functional programming languages. All the examples that I have seen for monads only describe the bind and unit methods. F# has lots of keywords (e.g. let!, do!, etc.) that allow you to do different things within the same computational expression. This seemingly gives you more power than your basic bind and unit methods. Is this unique to F# or is it common across functional programming languages?
Yes, I think that the F# syntax for computation expressions is unique in that it provides direct syntactic support for different types of computations. It can be used for working with monoids, usual monads and also MonadPlus computations from Haskell.
I wrote about these in the introduction of my Master thesis. I believe it is quite readable part, so you can go to page 27 to read it. Anyway, I'll copy the examples here:
Monoid is used just for concatenating values using some "+" operation (Combine). You can use it for example for building strings (this is inefficient, but it demonstrates the idea):
type StringMonoid() =
member x.Combine(s1, s2) = String.Concat(s1, s2)
member x.Zero() = ""
member x.Yield(s) = s
let str = new StringMonoid()
let hello = str { yield "Hello "
yield "world!" };;
Monads are the familiar example that uses bind and return operations of comptuation expressions. For example maybe monad represents computations that can fail at any point:
type MaybeMonad() =
member x.Bind(m, f) =
match m with Some(v) -> f v | None -> None
member x.Return(v) = Some(v)
let maybe = new MaybeMonad()
let rec productNameByID() = maybe {
let! id = tryReadNumber()
let! prod = db.TryFindProduct(id)
return prod.Name }
Additive monads (aka MonadPlus in Haskell) is a combination of the two. It is a bit like monadic computation that can produce multiple values. A common example is list (or sequence), which can implement both bind and combine:
type ListMonadPlus() =
member x.Zero() = []
member x.Yield(v) = [v]
member x.Combine(a, b) = a # b
member x.Bind(l, f) = l |> List.map f |> List.concat
let list = new ListMonadPlus()
let cities = list {
yield "York"
yield "Orleans" }
let moreCities = list {
let! n = cities
yield n
yield "New " + n }
// Creates: [ "York"; "New York"; "Orleans"; "New Orleans" ]
There are some additional keywords that do not directly correspond to any theoretical idea. The use keyword deals with resources and for and while can be used to implement looping. The sequence/list comprehension actually use for instead of let!, because that makes much more sense from the syntactic point of view (and for usually takes some sequence - although it may be e.g. asynchronous).
Monads are defined in terms of bind and unit operations (only). There are other structures which are defined by other operations (e.g. in Haskell, the MonadPlus typeclass has zero and plus operations - these correspond to Zero and Combine in F# computation expressions). As far as I know, F#'s computation builders are unique in terms of providing nice syntax for the wide range of operations that they support, but most of the operations are unrelated to monads.
F# binding forms ending in ! denote computation expressions, including let! use! do! yield! return!.
let! pat = expr in comp-expr -- binding computation
do! expr in comp-expr -- sequential computation
use! pat = expr in comp-expr -- auto cleanup computation
yield! expr -- yield computation
return! expr -- return computation
Computation expressions are used "for sequences and other non-standard interpretations of the F# expression syntax". These syntax forms offer ways to overload that syntax, for example, to encode monadic computations, or monoidal computations, and appear to be similar to e.g. the do-notation of Haskell, and corresponding (non-magic) bindings forms in that language.
So I would say that they support some overloading of syntax to support other interpretations of the expression syntax of the language, and this they have in common with many languages, including Haskell and OCaml. It is certainly a powerful and useful language feature.
References: The F# 2.0 Language Specification.
(Recall from memory, I may be off.)
While I think unit and bind are the typical basis for monads, I think maybe map and join for a different basis that I've seen in academic papers. This is kinda like how LINQ works in C# and VB, where the various from syntax desugars into Select or SelectMany which are similar to map and join. LINQ also has some 'extra' keywords, a little like F# though more ad-hoc (and mostly suited to querying enumerations/databases).
I don't know offhand of other functional languages like F# that effectively "lift" most of the control flow and other syntax into monads (well, "computation expressions", which may or may not be monads).
Sometimes in books I see this syntax for list and sequence comprehensions in F#:
seq { for i = 0 to System.Int32.MaxValue -> i }
This is from Programming F# by Chris Smith, page 80. In the F# which comes with VS2010, this doesn't compile. I believe -> has been deprecated. (See Alternative List Comprehension Syntax). However, -> can still be used in comprehensions which involve ranges:
seq { for c in 'A' .. 'Z' -> c }
According to Expert F# 2.0, page 58, this is because -> is shorthand for Seq.map over a range.
Why was the first usage of -> above deprecated?
The current use of -> seems inconsistent. Can anyone reconcile this for me?
The -> construct is supported only in the "simple" sequence expression syntax where you're doing a projection (Seq.map) over some data source using the following structure:
seq { for <binding> in <input> -> <projection> }
The first example you mentioned is using for .. to .. which is a different syntactical construct than for .. in, but you can rewrite it using the second one (In fact, I almost always use for .. in when writing sequence expressions):
seq { for i in 0 .. System.Int32.MaxValue -> i }
In all other forms of sequence expressions you'll have to use yield. In earlier versions of F#, the -> syntax was equivalent to yield (and there was also ->> which was equivalent to yield!). So for example, you was able to write:
seq { -> 10 // You need 'yield' here
->> [ 1; 2; 3 ] } // You need 'yield!' here
This syntax looks quite odd, so I think that the main reason for making these two deprecated is to keep the language consistent. The same computation expression syntax is used in sequence expressions (where -> makes some sense), but also for other computation types (and you can define your own), where yield feels more appropriate (and it also corresponds to return in asynchronous workflows or other computation expressions).
The "simple" sequence-specific syntax is still useful, because it saves you some typing (you replace do yield with just ->), but in more complicated cases, you don't save that many characters and I think that the syntax using -> & ->> can look a bit cryptic.