I am writing a library for C# developers. The library is written in F#. C# developers would like to use ++ operator on one of the objects. How can I do that ?
I looked up online, found that ++ post-increment operator is a no-such-thing in F#.
Even though F# does not have the ++ operator, you can still define an F# type that supports it:
type A(n:int) =
member x.N = n
static member op_Increment (a:A) = A(a.N + 1)
The trick is that you have to use the op_Increment name for the method, because that's what C# uses for the ++ operator. Unfortunately, F# does not understand the operator and so if you write member (++) ..., the compiler will call the method op_PlusPlus instead.
Related
How to use a three parametered infix operator?
Eg.: base function is
let orElse labelFunc p1 p2 = {...} and operator let ( <|> ) = orElse
Now, for non-infix version this works nicely:List.reduce ((<|>) labelFunc) parserList.
Can I use it somehow still "infixing"? eg.: (p1 (<|> labelFunc) p1) does not work nor any other combination, other than using the non-infix version here as well.
First of all, I think it's best to restrict the number of custom operators you're using in your code, because custom operators make F# code hard to read. F# lets you define custom operators, but it's not particularly designed to make this a great experience - it makes sense for some small domain-specific languages (like parser combinators), but not much else.
So, while I do not recommend using this, there is a weird trick that you can use to write something like p1 (<op> l) p2, which is to make <op> infix and replace the parentheses with two more custom operators:
let (</) a b = a, b
let (/>) c d = c, d
let (!) f = f
1 </ !10 /> 2
This sample just produces a tuple with all three arguments, but if you implement your logic in the </ operator, it will actually do something like what you want. But as I said, I would not do this :-).
I don't believe there is any good way to achieve that. Once you have a parenthesized expression it won't be parsed as an operator - even 1 (+) 1 doesn't work.
I am currently reading Programming in F# 3.0 and I read that F# supports partial function application.
But if I try
List.map (+1) [1 .. 10];;
Then I get error FS0001: This expression was expected to have type 'a -> 'b
but List.map (fun x -> x + 1) [1 .. 10];; compiles fine. Any ideas why?
I suppose you come from Haskell, for expecting it to work this way :)
Unfortunately, F# doesn't have the syntactic sugar where you can partially apply an operator by parenthesizing it preceded or followed by an expression. In your code, +1 is considered a single number token, which is why it complains that it is not a function.
What F# does have, however, is the syntax where you can parenthesize the operator alone. Which leads to #Lee's solution. Be careful about this syntax though: (+) 1 is equivalent to Haskell's (1+), not (+1). Obviously for addition it doesn't matter, but for asymmetrical operations such as subtraction, it can be misleading.
You need to put brackets around the +:
List.map ((+)1) [1..10]
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).
1- I'm really confusing on applying F# Quotation & Pattern on Meta Programming, please suggest some way to approach this concept in F#.
2- Can you show me some real application of F# Quotations and Pattern in Meta Programming ?
3- Some guys said that he can even make another language like IronScheme by F#,is that right ?
Thanks.
1- I'm really confusing on applying F# Quotation & Pattern on Meta Programming, please suggest some way to approach this concept in F#.
A quotation mechanism lets you embed code in your code and have the compiler transform that code from the source you provide into a data structure that represents it. For example, the following gives you a data structure representing the F# expression 1+2:
> <# 1+2 #>;;
val it : Quotations.Expr<int> =
Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (2)])
{CustomAttributes = [NewTuple (Value ("DebugRange"),
NewTuple (Value ("stdin"), Value (3), Value (3), Value (3), Value (6)))];
Raw = ...;
Type = System.Int32;}
You can then hack on this data structure in order to apply transformations to your code, such as translating it from F# to Javascript in order to run it client side on almost any browser.
2- Can you show me some real application of F# Quotations and Pattern in Meta Programming ?
The F# quotation mechanism is extremely limited in functionality compared to the quotation mechanisms of languages like OCaml and Lisp, to the point where I wonder why it was ever added. Moreover, although the .NET Framework and F# compiler provide everything required to compile and execute quoted code at full speed, the evaluation mechanism for quoted code is orders of magnitude slower than real F# code which, again, renders it virtually useless. Consequently, I am not familiar with any real applications of it beyond Websharper.
For example, you can only quote certain kinds of expressions in F# and not other code such as type definitions:
> <# type t = Int of int #>;;
<# type t = Int of int #>;;
---^^^^
C:\Users\Jon\AppData\Local\Temp\stdin(4,4): error FS0010: Unexpected keyword 'type' in quotation literal
Most quotation mechanisms let you quote any valid code at all. For example, OCaml's quotation mechanism can quote the type definition that F# just barfed on:
$ ledit ocaml dynlink.cma camlp4oof.cma
Objective Caml version 3.12.0
Camlp4 Parsing version 3.12.0
# open Camlp4.PreCast;;
# let _loc = Loc.ghost;;
val _loc : Camlp4.PreCast.Loc.t = <abstr>
# <:expr< 1+2 >>;;
- : Camlp4.PreCast.Ast.expr =
Camlp4.PreCast.Ast.ExApp (<abstr>,
Camlp4.PreCast.Ast.ExApp (<abstr>,
Camlp4.PreCast.Ast.ExId (<abstr>, Camlp4.PreCast.Ast.IdLid (<abstr>, "+")),
Camlp4.PreCast.Ast.ExInt (<abstr>, "1")),
Camlp4.PreCast.Ast.ExInt (<abstr>, "2"))
# <:str_item< type t = Int of int >>;;
- : Camlp4.PreCast.Ast.str_item =
Camlp4.PreCast.Ast.StSem (<abstr>,
Camlp4.PreCast.Ast.StTyp (<abstr>,
Camlp4.PreCast.Ast.TyDcl (<abstr>, "t", [],
Camlp4.PreCast.Ast.TySum (<abstr>,
Camlp4.PreCast.Ast.TyOf (<abstr>,
Camlp4.PreCast.Ast.TyId (<abstr>,
Camlp4.PreCast.Ast.IdUid (<abstr>, "Int")),
Camlp4.PreCast.Ast.TyId (<abstr>,
Camlp4.PreCast.Ast.IdLid (<abstr>, "int")))),
[])),
Camlp4.PreCast.Ast.StNil <abstr>)
FWIW, here is an example in Common Lisp:
$ sbcl
This is SBCL 1.0.29.11.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* '(+ 1 2)
(+ 1 2)
Metaprogramming is one application where pattern matching can be extremely useful but pattern matching is a general-purpose language feature. You may appreciate my article from the Benefits of OCaml about a minimal interpreter. In particular, note how easy pattern matching makes it to act upon each of the different kinds of expression:
> let rec eval vars = function
| EApply(func, arg) ->
match eval vars func, eval vars arg with
| VClosure(var, vars, body), arg -> eval ((var, arg) :: vars) body
| _ -> invalid_arg "Attempt to apply a non-function value"
| EAdd(e1, e2) -> VInt (int(eval vars e1) + int(eval vars e2))
| EMul(e1, e2) -> VInt (int(eval vars e1) * int(eval vars e2))
| EEqual(e1, e2) -> VBool (eval vars e1 = eval vars e2)
| EIf(p, t, f) -> eval vars (if bool (eval vars p) then t else f)
| EInt i -> VInt i
| ELetRec(var, arg, body, rest) ->
let rec vars = (var, VClosure(arg, vars, body)) :: vars in
eval vars rest
| EVar s -> List.assoc s vars;;
val eval : (string * value) list -> expr -> value = <fun>
That OCaml article was used as the basis of the F#.NET Journal article "Language-oriented programming: The Term-level Interpreter" (31st December 2007).
3- Some guys said that he can even make another language like IronScheme by F#,is that right ?
Yes, you can write compilers in F#. In fact, F# is derived from a family of languages that were specifically designed for metaprogramming, the so-called MetaLanguages (ML) family.
The article "Run-time code generation using System.Reflection.Emit" (31st August 2008) from the F#.NET Journal described the design and implementation of a simple compiler for a minimal language called Brainf*ck. You can extend this to implement more sophisticated languages like Scheme. Indeed, the F# compiler is mostly written in F# itself.
On a related note, I just completed a project writing high-performance serialization code that used reflection to consume F# types in a project and then spit out F# code to serialize and deserialize values of those types
F# quotations allow you to mark some piece of F# code and get the representation of the source code. This is ued in WebSharper (see for example this tutorial) to translate F# code to JavaScript. Another example is F# support for LINQ where code marked as <# ... #> is translated to SQL:
let res = <# for p in db.Products
if p.IsVisible then yield p.Name #> |> query
Pattern matching is simply a very powerful language construct, but it is nothing more mysterious than for example if. The idea is that you can match value against patterns and program will choose the first matching branch. This is powerful because patterns can be nested and so you can use it to process various complex data structures or implement symbolc processing:
match expr with
| Multiply(Constant 0, _) | Multiply(_, Constant 0) -> 0
| Multiply(expr1, expr2) -> (eval expr1) * (eval expr2)
// (other patterns)
For example, here we're using pattern matching to evaluate some representation of numerical expression. The first pattern is an optimization that deals with cases where one argument of multiplication is 0.
Writing languages You can use F# (just like any other general purpose language) to write compilers and tools for other languages. In F#, this is easy because it comes with tools for generating lexers and parsers. See for example this introduction.
Is it possible to provide an implementation for the C# equality (==) operator in F#?
EDIT:
This code:
static member (=) (left : Foo, right : Foo) =
Produces the compiler warning:
The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead.
The latter part addresses what I was trying to do. Any idea why op_Equality is favored over simply (=)?
Figured it out:
type Foo() =
static member op_Equality (left : Foo, right : Foo) =
Are you looking for operator overloading in F#?
The different operators are defined in CIL, so overloading loading an operator in F# would overload it in C#, VB.NET and any other .NET language that supports that operator.
Presumably, op_Equality is favored over (=) since the latter looks as if it ought to affect the equality operator within F#. That is, the behavior of the following code could be confusing:
type T() =
static member (=)(x:T,y:T) = true
let eq = (=) (T()) (T()) // false???