Rewriting Erlang in F# - f#

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.

Related

Is it possible to get the tag of an union at runtime?

I am working on a new version of the Spiral language and as one of its features, it will have structural equality and comparison similar to F#. But I am having difficulty figuring out how to compile that efficiently to F#.
The problem is that I cannot find how F# exposes tag information for its union cases.
For example, if I wrote cmp a b I'd like the Spiral compiler to generate something like the following F# code.
type T =
| A of int32
| B of float
let cmp_t = function
| A x, A x' -> cmp_i32 (x, x')
| B x, B x' -> cmp_f64 (x, x')
| x, x' -> cmp_i32 (union_tag x, union_tag x')
I've looked around and there are some proposals to expose the tag information, but nothing is out yet. I am wondering whether the F# compiler library has some functionality that I am not aware of for extracting the tag.
Otherwise for every union type, I am going to have to generate a custom tag function like...
let tag_t = function
| A _ -> 0
| B _ -> 1
But this can't be the right choice because F# has to be using some kind of tag under the hood for each of the union cases in order to differentiate them. It has to be able to know the tag for its own comparison function. Making tag functions like these would bloat the generated code and would be inefficient at runtime.
What should I do here?
You can use F# Reflection API for this.
Reflection.FSharpType.GetUnionCases can return you a full list of DU cases, each represented as a UnionCaseInfo structure, which has such useful properties as Name and Tag:
> Reflection.FSharpType.GetUnionCases(typeof<T>) |> Array.map (fun c -> c.Tag)
[|0; 1|]
And if you have a concrete value of the type (like in your cmp_t function), check out the Reflection.FSharpValue.GetUnionFields function, which, contrary to its name, will return you not only the fields, but also the UnionCaseInfo representing the case:
> let x = A 42
> let caseInfo, fields = Reflection.FSharpValue.GetUnionFields(x, typeof<T>)
> caseInfo.Tag
0
Keep in mind, however, that for F# discriminated unions the compiler will generate structural comparison automatically, so your cmpt_t function is redundant:
> A 42 < A 54
true
> A 3 > B 1.0
false
// Or more generally:
> (A 42 :> System.IComparable<T>).CompareTo(A 54)
-1
So your cmp_t can really be just this:
let cmp_t (x: 'a when 'a :> System.IComparable<'a>) y =
(x :> System.IComparable<'a>).CompareTo(y)
> cmp_t (A 42) (A 54)
-1
And behold! There is already such function in the standard library. It's called compare:
> compare (A 42) (A 54)
-1

Operator overloading for discriminated union

I'm trying to write some numerical code that can work with either scalars or vectors (in this case it's the D and DV types respectively, from DiffSharp). Sometimes I want to be able to use either so I've defined a discriminated union for them:
type IBroadcastable =
| Scalar of D
| Vect of DV
A lot of operators are already overloaded for both of these types, so to use them on IBroadcastable I write add code like this to the union:
static member Exp x =
match x with
| Scalar x -> Scalar (exp x)
| Vect x -> Vect (exp x)
This seems very redundant. Is there any way I can use the operator on the union without having to write a new overload for it? Or I should I be using a different pattern (i.e. not a discriminated union)? An example of what I want to use this type for:
let ll (y: IBroadcastable) (theta: IBroadcastable) = y*theta-(exp theta)
The * and - will have more complicated behaviour (array broadcasting), which it makes sense to have to describe myself, but the exp operator is simple, as above. This needs to be a function since I want to be able to partially apply the y argument, get the gradient with DiffSharp, and maximise it with respect to the theta argument.
Fundamentally, since you're defining an abstraction, you need to define your operations in terms of that abstraction. That's a cost that has to be offset by the convenience it affords you elsewhere in your code.
What you may be wondering is if F# will let you cut on the boilerplate in your particular case. Apart from using the function keyword, not really, because both branches are really doing different things: the type of the bound variable x is different, and you're wrapping them in different union cases. If you were really doing the same thing, you could write it as such, for example:
type DU =
| A of float * float
| B of float * string
with
static member Exp = function
| A (b, _)
| B (b, _) -> exp b // only write the logic once
Your sample function ll is actually even more generic - it can work on anything that supports the operations it uses, even things that are not D or DV. If you define it using inline, then you will be able to call the function on both:
let inline ll y theta = y*theta-(exp theta)
The inline modifier lets F# use static member constraints, which can be satisfied by the required members when calling the function (unlike with normal generic functions that have to be compiled using what .NET runtime provides).
I expect this will not work for all your code, because you will need some operations that are specific to D and DV, but do not have generic F# function such as exp. You can actually access those using static member constraints, though this gets a bit hairy.
Assuming D and DV values both have a member Foo returning string, you can write:
let inline foo (x:^T) =
(^T : (member Foo : string) x)
let inline ll y theta = y*theta-(exp theta)+foo y
You can cut down on the boilerplate by doing something like this:
type IBroadcastable =
| Scalar of D
| Vect of DV
let inline private lift s v = function
| Scalar d -> Scalar (s d)
| Vect dv -> Vect (v dv)
type IBroadcastable with
static member Exp b = lift exp exp b
static member Cos b = lift cos cos b
...
and if you want to support binary operators, you can define a corresponding lift2 - but carefully consider whether it makes sense for the first argument to a binary operator to be a Scalar value and the second to be a Vect (or vice versa) - if not, then your discriminated union might not be an appropriate abstraction.

Make Fish in F#

The Kleisli composition operator >=>, also known as the "fish" in Haskell circles, may come in handy in many situations where composition of specialized functions is needed. It works kind of like the >> operator, but instead of composing simple functions 'a -> 'b it confers some special properties on them possibly best expressed as 'a -> m<'b>, where m is either a monad-like type or some property of the function's return value.
Evidence of this practice in the wider F# community can be found e.g. in Scott Wlaschin's Railway oriented programming (part 2) as composition of functions returning the Result<'TSuccess,'TFailure> type.
Reasoning that where there's a bind, there must be also fish, I try to parametrize the canonical Kleisli operator's definition let (>=>) f g a = f a >>= g with the bind function itself:
let mkFish bind f g a = bind g (f a)
This works wonderfully with the caveat that generally one shouldn't unleash special operators on user-facing code. I can compose functions returning options...
module Option =
let (>=>) f = mkFish Option.bind f
let odd i = if i % 2 = 0 then None else Some i
let small i = if abs i > 10 then None else Some i
[0; -1; 9; -99] |> List.choose (odd >=> small)
// val it : int list = [-1; 9]
... or I can devise a function application to the two topmost values of a stack and push the result back without having to reference the data structure I'm operating on explicitly:
module Stack =
let (>=>) f = mkFish (<||) f
type 'a Stack = Stack of 'a list
let pop = function
| Stack[] -> failwith "Empty Stack"
| Stack(x::xs) -> x, Stack xs
let push x (Stack xs) = Stack(x::xs)
let apply2 f =
pop >=> fun x ->
pop >=> fun y ->
push (f x y)
But what bothers me is that the signature val mkFish : bind:('a -> 'b -> 'c) -> f:('d -> 'b) -> g:'a -> a:'d -> 'c makes no sense. Type variables are in confusing order, it's overly general ('a should be a function), and I'm not seeing a natural way to annotate it.
How can I abstract here in the absence of formal functors and monads, not having to define the Kleisli operator explicitly for each type?
You can't do it in a natural way without Higher Kinds.
The signature of fish should be something like:
let (>=>) (f:'T -> #Monad<'U>``) (g:' U -> #Monad<'V>) (x:'T) : #Monad<'V> = bind (f x) g
which is unrepresentable in current .NET type system, but you can replace #Monad with your specific monad, ie: Async and use its corresponding bind function in the implementation.
Having said that, if you really want to use a generic fish operator you can use F#+ which has it already defined by using static constraints. If you look at the 5th code sample here you will see it in action over different types.
Of course you can also define your own, but there is a lot of things to code, in order to make it behave properly in most common scenarios. You can grab the code from the library or if you want I can write a small (but limited) code sample.
The generic fish is defined in this line.
I think in general you really feel the lack of generic functions when using operators, because as you discovered, you need to open and close modules. It's not like functions that you prefix them with the module name, you can do that with operators as well (something like Option.(>=>)) , but then it defeats the whole purpose of using operators, I mean it's no longer an operator.

constrain generic type to inherit a generic type in f#

let mapTuple f (a,b) = (f a, f b)
I'm trying to create a function that applies a function f to both items in a tuple and returns the result as a tuple. F# type inference says that mapTuple returns a 'b*'b tuple. It also assumes that a and b are of the same type.
I want to be able to pass two different types as parameters. You would think that wouldn't work because they both have to be passed as parameters to f. So I thought if they inherited from the same base class, it might work.
Here is a less generic function for what I am trying to accomplish.
let mapTuple (f:Map<_,_> -> Map<'a,'b>) (a:Map<int,double>,b:Map<double, int>) = (f a, f b)
However, it gives a type mismatch error.
How do I do it? Is what I am trying to accomplish even possible in F#?
Gustavo is mostly right; what you're asking for requires higher-rank types. However,
.NET (and by extension F#) does support (an encoding of) higher-rank types.
Even in Haskell, which supports a "nice" way of expressing such types (once you've enabled the right extension), they wouldn't be inferred for your example.
Digging into point 2 may be valuable: given map f a b = (f a, f b), why doesn't Haskell infer a more general type than map :: (t1 -> t) -> t1 -> t1 -> (t, t)? The reason is that once you include higher-rank types, it's not typically possible to infer a single "most general" type for a given expression. Indeed, there are many possible higher-rank signatures for map given its simple definition above:
map :: (forall t. t -> t) -> x -> y -> (x, y)
map :: (forall t. t -> z) -> x -> y -> (z, z)
map :: (forall t. t -> [t]) -> x -> y -> ([x], [y])
(plus infinitely many more). But note that these are all incompatible with each other (none is more general than another). Given the first one you can call map id 1 'c', given the second one you can call map (\_ -> 1) 1 'c', and given the third one you can call map (\x -> [x]) 1 'c', but those arguments are only valid with each of those types, not with the other ones.
So even in Haskell you need to specify the particular polymorphic signature you want to use - this may be a bit of a surprise if you're coming from a more dynamic language. In Haskell, this is relatively clean (the syntax is what I've used above). However, in F# you'll have to jump through an additional hoop: there's no clean syntax for a "forall" type, so you'll have to create an additional nominal type instead. For example, to encode the first type above in F# I'd write something like this:
type Mapping = abstract Apply : 'a -> 'a
let map (m:Mapping) (a, b) = m.Apply a, m.Apply b
let x, y = map { new Mapping with member this.Apply x = x } (1, "test")
Note that in contrast to Gustavo's suggestion, you can define the first argument to map as an expression (rather than forcing it to be a member of some separate type). On the other hand, there's clearly a lot more boilerplate than would be ideal...
This problem has to do with rank-n types which are supported in Haskell (through extensions) but not in .NET type system.
One way I found to workaround this limitation is to pass a type with a single method instead of a function and then define an inline map function with static constraints, for example let's suppose I have some generic functions: toString and toOption and I want to be able to map them to a tuple of different types:
type ToString = ToString with static member inline ($) (ToString, x) = string x
type ToOption = ToOption with static member ($) (ToOption, x) = Some x
let inline mapTuple f (x, y) = (f $ x, f $ y)
let tuple1 = mapTuple ToString (true, 42)
let tuple2 = mapTuple ToOption (true, 42)
// val tuple1 : string * string = ("True", "42")
// val tuple2 : bool option * int option = (Some true, Some 42)
ToString will return the same type but operating with arbitrary types. ToOption will return two Generics of different types.
By using a binary operator type inference creates the static constraints for you and I use $ because in Haskell it means apply so a nice detail is that for haskellers f $ x reads already apply x to f.
At the risk of stating the obvious, a good enough solution might be to have a mapTuple that takes two functions instead of one:
let mapTuple fa fb (a, b) = (fa a, fb b)
If your original f is generic, passing it as fa and fb will give you two concrete instantiations of the function with the types you're looking for. At worst, you just need to pass the same function twice when a and b are of the same type.

What does -> mean in F#?

I've been trying to get into F# on and off for a while but I keep getting put off. Why?
Because no matter which 'beginners' resource I try to look at I see very simple examples that start using the operator ->.
However, nowhere have I found as yet that provides a clear simple explanation of what this operator means. It's as though it must be so obvious that it doesn't need explanation even to complete newbies.
I must therefore be really dense or perhaps it's nearly 3 decades of previous experience holding me back.
Can someone please, explain it or point to a truly accessible resource that explains it?
'->' is not an operator. It appears in the F# syntax in a number of places, and its meaning depends on how it is used as part of a larger construct.
Inside a type, '->' describes function types as people have described above. For example
let f : int -> int = ...
says that 'f' is a function that takes an int and returns an int.
Inside a lambda ("thing that starts with 'fun' keyword"), '->' is syntax that separates the arguments from the body. For example
fun x y -> x + y + 1
is an expression that defines a two argument function with the given implementation.
Inside a "match" construct, '->' is syntax that separates patterns from the code that should run if the pattern is matched. For example, in
match someList with
| [] -> 0
| h::t -> 1
the stuff to the left of each '->' are patterns, and the stuff on the right is what happens if the pattern on the left was matched.
The difficulty in understanding may be rooted in the faulty assumption that '->' is "an operator" with a single meaning. An analogy might be "." in C#, if you have never seen any code before, and try to analyze the "." operator based on looking at "obj.Method" and "3.14" and "System.Collections", you may get very confused, because the symbol has different meanings in different contexts. Once you know enough of the language to recognize these contexts, however, things become clear.
It basically means "maps to". Read it that way or as "is transformed into" or something like that.
So, from the F# in 20 minutes tutorial,
> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]
The code (fun i -> i % 2 = 0) defines
an anonymous function, called a lambda
expression, that has a parameter x and
the function returns the result of "x
% 2 = 0", which is whether or not x is
even.
First question - are you familiar with lambda expressions in C#? If so the -> in F# is the same as the => in C# (I think you read it 'goes to').
The -> operator can also be found in the context of pattern matching
match x with
| 1 -> dosomething
| _ -> dosomethingelse
I'm not sure if this is also a lambda expression, or something else, but I guess the 'goes to' still holds.
Maybe what you are really referring to is the F# parser's 'cryptic' responses:
> let add a b = a + b
val add: int -> int -> int
This means (as most of the examples explain) that add is a 'val' that takes two ints and returns an int. To me this was totally opaque to start with. I mean, how do I know that add isn't a val that takes one int and returns two ints?
Well, the thing is that in a sense, it does. If I give add just one int, I get back an (int -> int):
> let inc = add 1
val inc: int -> int
This (currying) is one of the things that makes F# so sexy, for me.
For helpful info on F#, I have found that blogs are FAR more useful that any of the official 'documentation': Here are some names to check out
Dustin Campbell (that's diditwith.net, cited in another answer)
Don Symes ('the' man)
Tomasp.net (aka Tomas Petricek)
Andrew Kennedy (for units of measure)
Fsharp.it (famous for the Project Euler solutions)
http://lorgonblog.spaces.live.com/Blog (aka Brian)
Jomo Fisher
(a -> b) means "function from a to b". In type annotation, it denotes a function type. For example, f : (int -> String) means that f refers to a function that takes an integer and returns a string. It is also used as a contstructor of such values, as in
val f : (int -> int) = fun n -> n * 2
which creates a value which is a function from some number n to that same number multiplied by two.
There are plenty of great answers here already, I just want to add to the conversation another way of thinking about it.
' -> ' means function.
'a -> 'b is a function that takes an 'a and returns a 'b
('a * 'b) -> ('c * 'd) is a function that takes a tuple of type ('a, 'b) and returns a tuple of ('c, 'd). Such as int/string returns float/char.
Where it gets interesting is in the cascade case of 'a -> 'b -> 'c. This is a function that takes an 'a and returns a function ('b -> 'c), or a function that takes a 'b -> 'c.
So if you write:
let f x y z = ()
The type will be f : 'a -> 'b -> 'c -> unit, so if you only applied the first parameter, the result would be a curried function 'b -> 'c -> 'unit.
From Microsoft:
Function types are the types given to
first-class function values and are
written int -> int. They are similar
to .NET delegate types, except they
aren't given names. All F# function
identifiers can be used as first-class
function values, and anonymous
function values can be created using
the (fun ... -> ...) expression form.
Many great answers to this questions, thanks people. I'd like to put here an editable answer that brings things together.
For those familiar with C# understanding -> being the same as => lamba expression is a good first step. This usage is :-
fun x y -> x + y + 1
Can be understood as the equivalent to:-
(x, y) => x + y + 1;
However its clear that -> has a more fundemental meaning which stems from concept that a function that takes two parameters such as the above can be reduced (is that the correct term?) to a series of functions only taking one parameter.
Hence when the above is described in like this:-
Int -> Int -> Int
It really helped to know that -> is right associative hence the above can be considered:-
Int -> (Int -> Int)
Aha! We have a function that takes Int and returns (Int -> Int) (a curried function?).
The explaination that -> can also appear as part of type definiton also helped. (Int -> Int) is the type of any of function which takes an Int and returns an Int.
Also helpful is the -> appears in other syntax such as matching but there it doesn't have the same meaning? Is that correct? I'm not sure it is. I suspect it has the same meaning but I don't have the vocabulary to express that yet.
Note the purpose of this answer is not to spawn further answers but to be collaboratively edited by you people to create a more definitive answer. Utlimately it would be good that all the uncertainies and fluf (such as this paragraph) be removed and better examples added. Lets try keep this answer as accessible to the uninitiated as possible.
In the context of defining a function, it is similar to => from the lambda expression in C# 3.0.
F#: let f = fun x -> x*x
C#: Func<int, int> f = x => x * x;
The -> in F# is also used in pattern matching, where it means: if the expression matches the part between | and ->, then what comes after -> should be given back as the result:
let isOne x = match x with
| 1 -> true
| _ -> false
The nice thing about languages such as Haskell (it's very similar in F#, but I don't know the exact syntax -- this should help you understand ->, though) is that you can apply only parts of the argument, to create curried functions:
adder n x y = n + x + y
In other words: "give me three things, and I'll add them together". When you throw numbers at it, the compiler will infer the types of n x and y. Say you write
adder 1 2 3
The type of 1, 2 and 3 is Int. Therefore:
adder :: Int -> Int -> Int -> Int
That is, give me three integers, and I will become an integer, eventually, or the same thing as saying:
five :: Int
five = 5
But, here's the nice part! Try this:
add5 = adder 5
As you remember, adder takes an int, an int, an int, and gives you back an int. However, that is not the entire truth, as you'll see shortly. In fact, add5 will have this type:
add5 :: Int -> Int -> Int
It will be as if you have "peeled off" of the integers (the left-most), and glued it directly to the function. Looking closer at the function signature, we notice that the -> are right-associative, i.e.:
addder :: Int -> (Int -> (Int -> Int))
This should make it quite clear: when you give adder the first integer, it'll evaluate to whatever's to the right of the first arrow, or:
add5andtwomore :: Int -> (Int -> Int)
add5andtwomore = adder 5
Now you can use add5andtwomore instead of "adder 5". This way, you can apply another integer to get (say) "add5and7andonemore":
add5and7andonemore :: Int -> Int
add5and7andonemore = adder 5 7
As you see, add5and7andonemore wants exactly another argument, and when you give it one, it will suddenly become an integer!
> add5and7andonemore 9
=> ((add5andtwomore) 7) 9
=> ((adder 5) 7) 9)
<=> adder 5 7 9
Substituting the parameters to adder (n x y) for (5 7 9), we get:
> adder 5 7 9 = 5 + 7 + 9
=> 5 + 7 + 9
=> 21
In fact, plus is also just a function that takes an int and gives you back another int, so the above is really more like:
> 5 + 7 + 9
=> (+ 5 (+ 7 9))
=> (+ 5 16)
=> 21
There you go!

Resources