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
Related
I have found a presentation by Don Syme which shows that Erlang's
fac(0) -> 1
fac(N) -> N * fac(N-1).
is equivalent to F#'s
let rec fac = function
| 0 -> 1
| n -> n * fac (n-1)
But it looks like there is no way to use pattern matching for a different arity without losing type safety. E.g. one could use a list pattern matching, but then a type must be a common base type (such as object):
let concat = function
| [x;y] -> x.ToString() + y.ToString()
| [x] -> x.ToString()
Given that F# functions in modules do not support overloads, it looks like the only way to rewrite Erlang code into F# with static typing is to use static classes with method overloading instead of modules. Is there a better way to rewrite Erlang functions with different arity in F#?
In general, is it correct to say that Erlang's argument matching is closer to .NET's (including C#) method overloading rather than to F#'s pattern matching? Or there is no direct replacement between the two, e.g. there could be a function in Erlang with different arities + a guard:
max(x) -> x.
max(x,y) when x > y -> x.
max(x,y) -> y.
max(comparer, x, y) -> if comparer(x,y) > 0 -> x; true -> y end.
In the last case the arguments are of different types. How would you rewrite it in F#?
You can achieve something close to overloading by rethinking the problem slightly. Instead of thinking about the function as the axis of variability, think of the input as the variable part. If you do that, you'll realise that you can achieve the same with a discriminated union.
Here's a more contrived example than the one in the linked article:
type MyArguments = One of int | Two of int * int
let foo = function
| One x -> string x
| Two (x, y) -> sprintf "%i%i" x y
Usage:
> foo (One 42);;
val it : string = "42"
> foo (Two (13, 37));;
val it : string = "1337"
Obviously, instead of defining such a 'stupid' type as the above MyArguments, you'd define a discriminated union that makes sense in the domain you're modelling.
Being relatively new to functional programming, I am still unfamiliar with all the standard operators. The fact that their definition is allowed to be arbitrary in many languages and also that such definitions aren't available in nearby source code, if at all, makes reading functional code unnecessarily challenging.
Presently, I don't know what <*> as it occurs in WebSharper.UI.Next documentation.
It would be good if there was a place that listed all the conventional definition for the various operators of the various functional languages.
I agree with you, it would be good to have a place where all implicit conventions for operators used in F# are listed.
The <*> operator comes from Haskell, it's an operator for Applicative Functors, its general signature is: Applicative'<('A -> 'B)> -> Applicative'<'A> -> Applicative'<'B> which is an illegal signature in .NET as higher kinds are not supported.
Anyway nothing stops you from defining the operator for a specific Applicative Functor, here's the typical definition for option types:
let (<*>) f x =
match (f, x) with
| Some f, Some x -> Some (f x)
| _ -> None
Here the type is inferred as:
val ( <*> ) : f:('a -> 'b) option -> x:'a option -> 'b option
which is equivalent to:
val ( <*> ) : f: option<('a -> 'b)> -> x: option<'a> -> option<'b>
The intuitive explanation is that it takes a function in a context and an argument for that function in the context, then it executes the function inside the context.
In our example for option types it can be used for applying a function to a result value of an operation which may return a None value:
let tryParse x =
match System.Int32.TryParse "100" with
| (true, x) -> Some x
| _ -> None
Some ((+) 10) <*> tryParse "100"
You can take advantage of currying and write:
Some (+) <*> tryParse "100" <*> Some 10
Which represents something like:
(+) (System.Int32.Parse "100") 10
but without throwing exceptions, that's why it is also said that Applicatives are used to model side-effects, specially in pure functional languages like Haskell. Here's another sample of option applicatives.
But for different types it has different uses, for lists it may be used to zip them as shown in this post.
In F# it's not defined because .NET type system would not make it possible to define it in a generic way however it would be possible using overloads and static member constraints as in FsControl otherwise you will have to select different instances by hand by opening specific modules, which is the approach used in FSharpx.
Just discovered elsewhere in the documentation on another subject...
let ( <*> ) f x = View.Apply f x
where type of View.Apply and therefore ( <*> ) is:
View<'A * 'B> -> View<'A> -> View<'B>
Ok, so I'm basically trying to add the bind operator to the option type and it seems that everything I try has some non-obvious caveat that prevent me from doing it. I suspect is has something to do with the limits of the .NET typesystem and is probably the same reason typeclasses can't be implemented in user code.
Anyways, I've attempted a couple of things.
First, I tried just the following
let (>>=) m f = ???
realizing that I want to do different things based on the type of m. F# doesn't allow overloads on function but .NET does allow them on methods, so attempt number two:
type Mon<'a> =
static member Bind(m : Option<'a>, f : ('a -> Option<'b>)) =
match m with
| None -> None
| Some x -> f x
static member Bind(m : List<'a>, f : ('a -> List<'b>)) =
List.map f m |> List.concat
let (>>=) m f = Mon.Bind(m, f)
No dice. Can't pick a unique overload based on previously given type info. Add type annotations.
I've tried making the operator inline but it still gives the same error.
Then I figured I could make the >>= operator a member of a type. I'm pretty sure this would work but I don't think I can hack it in on existing types. You can extend existing types with type Option<'a> with but you can't have operators as extensions.
That was my last attempt with this code:
type Option<'a> with
static member (>>=) (m : Option<'a>, f : ('a -> Option<'b>)) =
match m with
| None -> None
| Some x -> f x
"Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead." Awesome.
Do I have any other option? I could define separate functions for different monads in separate modules but that sounds like hell if you want to use more than one version in the same file.
You can combine .NET overload resolution with inline/static constraints in order to get the desired behaviour.
Here's a step by step explanation and here's a small working example for your specific scenario:
type MonadBind = MonadBind with
static member (?<-) (MonadBind, m:Option<'a>, _:Option<'b>) =
fun (f:_->Option<'b>) ->
match m with
| None -> None
| Some x -> f x
static member (?<-) (MonadBind, m:List<'a>, _:List<'b>) =
fun (f:_->List<'b>) ->
List.map f m |> List.concat
let inline (>>=) m f : 'R = ( (?<-) MonadBind m Unchecked.defaultof<'R>) f
[2; 1] >>= (fun x -> [string x; string (x+2)]) // List<string> = ["2"; "4"; "1"; "3"]
Some 2 >>= (fun x -> Some (string x)) // Option<string> = Some "2"
You can also specify the constraints 'by hand', but when using operators they're inferred automatically.
A refinement of this technique (without the operators) is what we use in FsControl to define Monad, Functor, Arrow and other abstractions.
Also note you can use directly Option.bind and List.collect for both bind definitions.
Why do you need to (re-define) "bind"? For starters, Option.bind is already defined.
You can use it for defining a "computational expression builder" (F# name for monadic "do" syntax sugar).
See previous answer.
Further to my last question:
let safeInput:Map<'a,'b> option -> 'a -> 'b -> Map<'a,'b> option = fun x y z ->
match x with
| Some d -> Some(d.Add(y,z))
| None -> Some([y,z]|>Map.ofList)
I understand how simple higher-order functions are declared as a type... reading from right to left if '->' is used more than once to decipher what it returns.. i.e. a higher order function.
For the above example from a book... I understand this is adding to a map, I'm just a bit hazy on how the top line should be deciphered? And the use of the 'fun' keyword?
So the first line states that safeInput is a function which takes a Map option a key a value and then returns a map option. The fun keyword is just a way of creating the function.
An equivalent function is
let safeInput (x:Map<'a,'b> option) (y:'a) (z:'b) :Map<'a,'b> option =
match x with
| Some d -> Some(d.Add(y,z))
| None -> Some([y,z]|>Map.ofList)
As I'm reading the Programming F# book, I found the example code snippet on page 195 as follows:
type ContinuationStep<'a> =
| Finished
| Step of 'a * (unit -> ContinuationStep<'a>)
let iter f binTree =
let rec linearize binTree cont =
match binTree with
| Empty -> cont()
| Node(x, l, r) ->
Step(x, (fun () -> linearize l (fun() -> linearize r cont)))
let steps = linearize binTree (fun () -> Finished)
let rec processSteps step =
match step with
| Finished -> ()
| Step(x, getNext)
-> f x
processSteps (getNext())
processSteps steps
By using continuation, the binary recursion of traversing a binary has been transformed to tail-recursive function processSteps. My question is that the other function, linearize seems to be non-tail-recursive. Does that mean we are not able to transform a binary-recursion to a tail-recursion completely even using continuation?
linearize is tail-recursive: you don't need to come back from the recursive call to continue the computation.
fun () -> linearize l (fun() -> linearize r cont)
doesn't call linearize. The computation is suspended until processSteps calls getNext ().
The example is a bit subtle because it does not use ordinary continuations, but instead builds a structure that can be evaluated step-by-step. In a place where you would normally make a recursive call, it returns a value Step that contains the function that you'd (recursively) call.
In the second case, the linearize function returns a Step containing a function that will call linearize recursively, but it does not immediately make the recursive call. So the function does not make a recursive call (it just stores a recursive reference).
It only makes sense to consider whether the program is tail-recursive when you look at processSteps, because that does the actual looping - and that is tail-recursive, because it runs a Step by Step without keeping stack space for each Step.
If you wanted to construct a list instead of a chain of lazy steps then you'd have to make the recursive call to linearize immediately inside the continuation:
let rec linearize binTree cont =
match binTree with
| Empty -> cont []
| Node(x, l, r) ->
linearize l (fun l -> linearize r (fun v -> cont (x::v)))
This is essentially the same as the previous function, but it actually calls linearize instead of building Step containing a function that will call linearize.