Scala read-eval-print using RegexParser without so much boilerplate? - parsing

I'm implementing part of a Scala program that takes input strings of the form "functionName arg1=x1 arg2=x2 ...", parses the xi to the correct types, and then calls a corresponding Scala function functionName(x1,x2,...). The code below is an example implementation with two functions foo and bar, which take different kinds of arguments.
Notice that the types and argument names of foo and bar have to be handwritten into the code in several places: the original function definitions, defining the case classes that the parser returns, and the parsers themselves. The case classes returned by the parser also do basically nothing interesting -- I'm tempted to just call foo and bar from within the parser, but I feel like that would be icky.
My question is: can this implementation be simplified? In practice, I will have many functions with complicated argument types, and I'd prefer to be able to specify those types as few times as possible, and perhaps also not have to define corresponding case classes.
type Word = String
// the original function definitions
def foo(x: Int, w: Word) = println("foo called with " + x + " and " + w)
def bar(y: Int, z: Int) = println("bar called with " + y + " and " + z)
// the return type for the parser
abstract class Functions
case class Foo(x: Int, w: Word) extends Functions
case class Bar(y: Int, z: Int) extends Functions
object FunctionParse extends RegexParsers {
val int = """-?\d+""".r ^^ (_.toInt)
val word = """[a-zA-Z]\w*""".r
val foo = "foo" ~> ("x=" ~> int) ~ ("w=" ~> word) ^^ { case x~w => Foo(x,w) }
val bar = "bar" ~> ("y=" ~> int) ~ ("z=" ~> int) ^^ { case y~z => Bar(y,z) }
val function = foo | bar
def parseString(s: String) = parse(function, s)
}
def main(args: Array[String]) = {
FunctionParse.parseString(args.mkString(" ")) match {
case FunctionParse.Success(result, _) => result match {
case Foo(x, w) => foo(x, w)
case Bar(y, z) => bar(y, z)
}
case _ => println("sux.")
}
}
Edit: I should note that in my case, the specific format above for the input string is not very important -- I'm happy to change it (use xml or whatever) if it results in cleaner, simpler Scala code.

You want reflection, to put it simply. Reflection means finding out, instantiating and calling classes and methods at runtime instead of compile time. For example:
scala> val clazz = Class forName "Foo"
clazz: Class[_] = class Foo
scala> val constructors = clazz.getConstructors
constructors: Array[java.lang.reflect.Constructor[_]] = Array(public Foo(int,java.lang.String))
scala> val constructor = constructors(0)
constructor: java.lang.reflect.Constructor[_] = public Foo(int,java.lang.String)
scala> constructor.getParameter
getParameterAnnotations getParameterTypes
scala> val parameterTypes = constructor.getParameterTypes
parameterTypes: Array[Class[_]] = Array(int, class java.lang.String)
scala> constructor.newInstance(5: Integer, "abc")
res6: Any = Foo(5,abc)
This is all Java reflection. Scala 2.9 still doesn't have a Scala-specific reflection interface, though one is already in development and might well be available on the next version of Scala.

What you're doing looks very reasonable. The only way to 'simplify' it in my mind would be to have less explicit types and/or use reflection to look up the appropriate function...
Update: Daniel's answer is a good example of how to use reflection. In terms of less explicit types, you would have to have the function arguments to be Any...

Related

What is missing using interfaces compared to true type-classes?

F# does not (currently) support type-classes. However, F# does support the OOP aspects of C#.
I was wondering, what is lost doing this approach compared to true type-classes?
// A concrete type
type Foo =
{
Foo : int
}
// "Trait" for things that can be shown
type IShowable =
abstract member Show : unit -> string
module Showable =
let show (showable : IShowable) =
showable.Show()
// "Witness" of IShowable for Foo
module Foo =
let asShowable (foo : Foo) =
{
new IShowable with
member this.Show() = string foo.Foo
}
// Slightly awkward usage
{ Foo = 123 }
|> Foo.asShowable
|> Showable.show
|> printfn "%s"
Your suggestion works for simple typeclasses that operate on a single value of a type, like Show. However, what happens when you need a typeclass that isn't so object-oriented? For example, when we want to add two numbers, neither one corresponds to OO's this object:
// not real F#
typeclass Numeric<'a> = // e.g. Numeric<int> or Numeric<float>
abstract member (+) : 'a -> 'a -> 'a // e.g. 2 + 3 = 5 or 2.0 + 3.0 = 5.0
...
Also, keep in mind that many useful typeclasses require higher-kinded types. For example, consider the monad typeclass, which would look something like this:
// not real F#
typeclass Monad<'m<_>> = // e.g. Monad<Option<_>> or Monad<Async<_>>
abstract member Return<'a> : 'a -> 'm<'a>
abstract member Bind<'a, 'b> : 'm<'a> -> ('a -> 'm<'b>) -> 'm<'b>
There's no good way to do this with .NET interfaces.
Higher-kinded type classes are indeed impossible to model with interfaces, but that's just because F# does not support higher-kindedness, not because of type classes themselves.
The deeper thing to note is that your encoding isn't actually correct. Sure, if you just need to call show directly, you can do asShowable like that, but that's just the simplest case. Imagine you needed to pass the value to another function that wanted to show it later? And then imagine it was a list of values, not a single one:
let needsToShow (showable: IShowable) (xs: 'a list) =
xs |> List.iter (fun x -> ??? how do I show `x` ???)
No, this wouldn't do of course. The key is that Show should be a function 'a -> string, not unit -> string. And this means that IShowable itself should be generic:
// Haskell: class Showable a where show :: a -> String
type IShowable<'a> with
abstract member Show : 'a -> string
// Haskell: instance Showable Foo where show (Foo i) = show i
module Foo =
let showable = { new IShowable<Foo> with member _.Show foo = string foo.Foo }
// Haskell: needsToShow :: Show a => [a] -> IO ()
let needsToShow (showable: IShowable<'a>) (xs: 'a list) =
xs |> List.iter (fun x -> printfn "%s" (showable.Show x))
// Haskell: needsToShow [Foo 1, Foo 42]
needsToShow Foo.showable [ { Foo: 1 }; { Foo: 42 } ]
And this is, essentially, what type classes are: they're indeed merely dictionaries of functions that are passed everywhere as extra parameters. Every type has such dictionary either available right away (like Foo above) or constructable from other such dictionaries, e.g.:
type Bar<'a> = Bar of 'a
// Haskell: instance Show a => Show (Bar a) where show (Bar a) = "Bar: " <> show a
module Bar =
let showable (showA: IShowable<'a>) =
{ new IShowable<Bar<'a>> with member _.Show (Bar a) = "Bar: " + showA.Show a }
This is completely equivalent to type classes. And in fact, this is exactly how they're implemented in languages like Haskell or PureScript in the first place: like dictionaries of functions being passed as extra parameters. It's not a coincidence that constraints on function type signatures even kinda look like parameters - just with a fat arrow instead of a thin one.
The only real difference is that in F# you have to do that yourself, while in Haskell the compiler figures out all the instances and passes them for you.
And this difference turns out to be kind of important in practice. I mean, sure, for such a simple example as Show for the immediate parameter, you can just pass the damn instance yourself. And even if it's more complicated, I guess you could suck it up and pass a dozen extra parameters.
But where this gets really inconvenient is operators. Operators are functions too, but with operators there is nowhere to stick an extra parameter (or dozen). Check this out:
x = getY >>= \y -> getZ y <&> \z -> y + 42 > z
Here I used four operators from four different classes:
>>= comes from Monad
<&> from Functor
+ from Num
> from Ord
An equivalent in F# with passing instances manually might look something like:
let x =
bind Foo.monad getY <| fun y ->
map Bar.functor (getZ y) <| fun z ->
gt Int.ord (add Int.num y 42) z
Having to do that everywhere is quite unreasonable, you have to agree.
And this is why many F# operators either use SRTPs (e.g. +) or rely on "known" interfaces (e.g. <) - all so you don't have to pass instances manually.

How I can convert concrete syntax values to other kinds of values?

Given some concrete syntax value, how I can I map it to a different type of value (in this case an int)?
// Syntax
start syntax MyTree = \node: "(" MyTree left "," MyTree right ")"
| leaf: Leaf leaf
;
layout MyLayout = [\ \t\n\r]*;
lexical Leaf = [0-9]+;
This does not work unfortunately:
public Tree increment() {
MyTree tree = (MyTree)`(3, (1, 10))`;
return visit(tree) {
case l:(Leaf)`3` => l + 1
};
}
Or is the only way to implode into an ADT where I specified the types?
Your question has different possible answers:
using implode you can convert a parse tree to an abstract tree. If the constructors of the target abstract language expect int, then lexical trees which happen to match [0-9]+ will be automatically converted. For example the syntax tree for syntax Exp = intValue: IntValue; could be converted to constructor data Exp = intValue(int i); and it will actually build an i.
in general to convert one type of values to another in Rascal you write (mutually) recursive functions, as in int eval (MyTree t) and int (Leaf l).
if you want to actually increment the syntactic representation of a Leaf value, you have to convert back (parse or via a concrete pattern) from the resulting int back to the Leaf.
Example:
import String;
MyTree increment() {
MyTree tree = (MyTree)`(3, (1, 10))`;
return visit(tree) {
case Leaf l => [Leaf] "<toInt("<l>") + 1>";
};
}
First the lexical is converted to a string "<l>", this is then parsed as an int using toInt() and we add 1 using + 1 and then map the int back to a string "< ... >", after which we can call the Leaf parser using [Leaf].

Idiomatic way to declare static and instance member at once?

When I extend a type with a new function, I usually want it to be available from both dot-notation and free form. Either can be more readable depending on the situation, and the former helps with IntelliSense while the latter helps with currying.
In C#/VB.net, extension methods do this (although I cannot restrict the function to a static method of the extended static class, as in F#). I can write the function once and then invoke it both ways:
<Extension>
public function bounded(s as string, min as UShort, max as UShort) as string
if min > max then throw new ArgumentOutOfRangeException
if string.IsNullOrEmpty(s) then return new string(" ", min)
if s.Length < min then return s.PadRight(min, " ")
if s.Length > max then return s.Substring(0, max)
return s
end function
' usage
dim b1 = bounded("foo", 10, 15)
dim b2 = "foo".bounded(0, 2)
(That's not quite perfect yet, as I'd like bounded to be a static method of String, but C#/VB.Net can't do that. Point to F# in that regard.)
In F#, on the other side, I have to declare the function separatedly from the method:
// works fine
[<AutoOpen>]
module Utilities =
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
module List =
let tryHead (l : List<'T>) = l.tryHead
Question: Is there a more elegant way to declare both methods at once?
I tried to use:
// doesn't quite work
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
static member tryHead(l : List<'T>) = l.tryHead
which at least would let me skip the module declaration, but while the definition compiles, it doesn't quite work - someList.tryHead is OK, but List.tryHead someList results in a Property tryHead is not static error.
Bonus question: As you can see, the static member definition requires a type annotation. However, no other type could have access to the method that was just defined. Why, then, can't the type be inferred?
I don't know of a way to declare both APIs in a single line of code, but you can get rid of the type annotations by making the function the implementation, and then defining the method it terms of the function:
[<AutoOpen>]
module Utilities =
module List =
let tryHead l = if List.isEmpty l then None else Some (List.head l)
type List<'a> with
member this.tryHead = List.tryHead this

How does F# compile functions that can take multiple different parameter types into IL?

I know virtually nothing about F#. I don’t even know the syntax, so I can’t give examples.
It was mentioned in a comment thread that F# can declare functions that can take parameters of multiple possible types, for example a string or an integer. This would be similar to method overloads in C#:
public void Method(string str) { /* ... */ }
public void Method(int integer) { /* ... */ }
However, in CIL you cannot declare a delegate of this form. Each delegate must have a single, specific list of parameter types. Since functions in F# are first-class citizens, however, it would seem that you should be able to pass such a function around, and the only way to compile that into CIL is to use delegates.
So how does F# compile this into CIL?
This question is a little ambiguous, so I'll just ramble about what's true of F#.
In F#, methods can be overloaded, just like C#. Methods are always accessed by a qualified name of the form someObj.MethodName or someType.MethodName. There must be context which can statically resolve the overload at compile-time, just as in C#. Examples:
type T() =
member this.M(x:int) = ()
member this.M(x:string) = ()
let t = new T()
// these are all ok, just like C#
t.M(3)
t.M("foo")
let f : int -> unit = t.M
let g : string-> unit = t.M
// this fails, just like C#
let h = t.M // A unique overload for method 'M' could not be determined
// based on type information prior to this program point.
In F#, let-bound function values cannot be overloaded. So:
let foo(x:int) = ()
let foo(x:string) = () // Duplicate definition of value 'foo'
This means you can never have an "unqualified" identifier foo that has overloaded meaning. Each such name has a single unambiguous type.
Finally, the crazy case which is probably the one that prompts the question. F# can define inline functions which have "static member constraints" which can be bound to e.g. "all types T that have a member property named Bar" or whatnot. This kind of genericity cannot be encoded into CIL. Which is why the functions that leverage this feature must be inline, so that at each call site, the code specific-to-the-type-used-at-that-callsite is generated inline.
let inline crazy(x) = x.Qux(3) // elided: type syntax to constrain x to
// require a Qux member that can take an int
// suppose unrelated types U and V have such a Qux method
let u = new U()
crazy(u) // is expanded here into "u.Qux(3)" and then compiled
let v = new V()
crazy(v) // is expanded here into "v.Qux(3)" and then compiled
So this stuff is all handled by the compiler, and by the time we need to generate code, once again, we've statically resolved which specific type we're using at this callsite. The "type" of crazy is not a type that can be expressed in CIL, the F# type system just checks each callsite to ensure the necessary conditions are met and inlines the code into that callsite, a lot like how C++ templates work.
(The main purpose/justification for the crazy stuff is for overloaded math operators. Without the inline feature, the + operator, for instance, being a let-bound function type, could either "only work on ints" or "only work on floats" or whatnot. Some ML flavors (F# is a relative of OCaml) do exactly that, where e.g. the + operator only works on ints, and a separate operator, usually named +., works on floats. Whereas in F#, + is an inline function defined in the F# library that works on any type with a + operator member or any of the primitive numeric types. Inlining can also have some potential run-time performance benefits, which is also appealing for some math-y/computational domains.)
When you're writing C# and you need a function that can take multiple different parameter sets, you just create method overloads:
string f(int x)
{
return "int " + x;
}
string f(string x)
{
return "string " + x;
}
void callF()
{
Console.WriteLine(f(12));
Console.WriteLine(f("12"));
}
// there's no way to write a function like this:
void call(Func<int|string, string> func)
{
Console.WriteLine(func(12));
Console.WriteLine(func("12"));
}
The callF function is trivial, but my made-up syntax for the call function doesn't work.
When you're writing F# and you need a function that can take multiple different parameter sets, you create a discriminated union that can contain all the different parameter sets and you make a single function that takes that union:
type Either = Int of int
| String of string
let f = function Int x -> "int " + string x
| String x -> "string " + x
let callF =
printfn "%s" (f (Int 12))
printfn "%s" (f (String "12"))
let call func =
printfn "%s" (func (Int 12))
printfn "%s" (func (String "12"))
Being a single function, f can be used like any other value, so in F# we can write callF and call f, and both do the same thing.
So how does F# implement the Either type I created above? Essentially like this:
public abstract class Either
{
public class Int : Test.Either
{
internal readonly int item;
internal Int(int item);
public int Item { get; }
}
public class String : Test.Either
{
internal readonly string item;
internal String(string item);
public string Item { get; }
}
}
The signature of the call function is:
public static void call(FSharpFunc<Either, string> f);
And f looks something like this:
public static string f(Either _arg1)
{
if (_arg1 is Either.Int)
return "int " + ((Either.Int)_arg1).Item;
return "string " + ((Either.String)_arg1).Item;
}
Of course you could implement the same Either type in C# (duh!), but it's not idiomatic, which is why it wasn't the obvious answer to the previous question.
Assuming I understand the question, in F# you can define expressions which depend on the availability of members with particular signatures. For instance
let inline f x a = (^t : (member Method : ^a -> unit)(x,a))
This defines a function f which takes a value x of type ^t and a value a of type ^a where ^t has a method Method taking an ^a to unit (void in C#), and which calls that method. Because this function is defined as inline, the definition is inlined at the point of use, which is the only reason that it can be given such a type. Thus, although you can pass f as a first class function, you can only do so when the types ^t and ^a are statically known so that the method call can be statically resolved and inserted in place (and this is why the type parameters have the funny ^ sigil instead of the normal ' sigil).
Here's an example of passing f as a first-class function:
type T() =
member x.Method(i) = printfn "Method called with int: %i" i
List.iter (f (new T())) [1; 2; 3]
This runs the method Method against the three values in the list. Because f is inlined, this is basically equivalent to
List.iter ((fun (x:T) a -> x.Method(a)) (new T())) [1; 2; 3]
EDIT
Given the context that seems to have led to this question (C# - How can I “overload” a delegate?), I appear not to have addressed your real question at all. Instead, what Gabe appears to be talking about is the ease with which one can define and use discriminated unions. So the question posed on that other thread might be answered like this using F#:
type FunctionType =
| NoArgument of (unit -> unit)
| ArrayArgument of (obj[] -> unit)
let doNothing (arr:obj[]) = ()
let doSomething () = printfn "'doSomething' was called"
let mutable someFunction = ArrayArgument doNothing
someFunction <- NoArgument doSomething
//now call someFunction, regardless of what type of argument it's supposed to take
match someFunction with
| NoArgument f -> f()
| ArrayArgument f -> f [| |] // pass in empty array
At a low level, there's no CIL magic going on here; it's just that NoArgument and ArrayArgument are subclasses of FunctionType which are easy to construct and to deconstruct via pattern matching. The branches of the pattern matching expression are morally equivalent to a type test followed by property accesses, but the compiler makes sure that the cases have 100% coverage and don't overlap. You could encode the exact same operations in C# without any problem, but it would be much more verbose and the compiler wouldn't help you out with exhaustiveness checking, etc.
Also, there is nothing here which is particular to functions; F# discriminated unions make it easy to define types which have a fixed number of named alternatives, each one of which can have data of whatever type you'd like.
I'm not quite sure that understand your question correctly... F# compiler uses FSharpFunc type to represent functions. Usually in F# code you don't deal with this type directly, using fancy syntactic representation instead, but if you expose any members that returns or accepts function and use them from another language, line C# - you will see it.
So instead of using delegates - F# utilizes its special type with concrete or generic parameters.
If your question was about things like add something-i-don't-know-what-exactly-but-it-has-addition-operator then you need to use inline keyword and compiler will emit function body in the call site. #kvb's answer was describing exactly this case.

"int -> int -> int" What does this mean in F#?

I wonder what this means in F#.
“a function taking an integer, which returns a function which takes an integer and returns an integer.”
But I don't understand this well.
Can anyone explain this so clear ?
[Update]:
> let f1 x y = x+y ;;
val f1 : int -> int -> int
What this mean ?
F# types
Let's begin from the beginning.
F# uses the colon (:) notation to indicate types of things. Let's say you define a value of type int:
let myNumber = 5
F# Interactive will understand that myNumber is an integer, and will tell you this by:
myNumber : int
which is read as
myNumber is of type int
F# functional types
So far so good. Let's introduce something else, functional types. A functional type is simply the type of a function. F# uses -> to denote a functional type. This arrow symbolizes that what is written on its left-hand side is transformed into what is written into its right-hand side.
Let's consider a simple function, that takes one argument and transforms it into one output. An example of such a function would be:
isEven : int -> bool
This introduces the name of the function (on the left of the :), and its type. This line can be read in English as:
isEven is of type function that transforms an int into a bool.
Note that to correctly interpret what is being said, you should make a short pause just after the part "is of type", and then read the rest of the sentence at once, without pausing.
In F# functions are values
In F#, functions are (almost) no more special than ordinary types. They are things that you can pass around to functions, return from functions, just like bools, ints or strings.
So if you have:
myNumber : int
isEven : int -> bool
You should consider int and int -> bool as two entities of the same kind: types. Here, myNumber is a value of type int, and isEven is a value of type int -> bool (this is what I'm trying to symbolize when I talk about the short pause above).
Function application
Values of types that contain -> happens to be also called functions, and have special powers: you can apply a function to a value. So, for example,
isEven myNumber
means that you are applying the function called isEven to the value myNumber. As you can expect by inspecting the type of isEven, it will return a boolean value. If you have correctly implemented isEven, it would obviously return false.
A function that returns a value of a functional type
Let's define a generic function to determine is an integer is multiple of some other integer. We can imagine that our function's type will be (the parenthesis are here to help you understand, they might or might not be present, they have a special meaning):
isMultipleOf : int -> (int -> bool)
As you can guess, this is read as:
isMultipleOf is of type (PAUSE) function that transforms an int into (PAUSE) function that transforms an int into a bool.
(here the (PAUSE) denote the pauses when reading out loud).
We will define this function later. Before that, let's see how we can use it:
let isEven = isMultipleOf 2
F# interactive would answer:
isEven : int -> bool
which is read as
isEven is of type int -> bool
Here, isEven has type int -> bool, since we have just given the value 2 (int) to isMultipleOf, which, as we have already seen, transforms an int into an int -> bool.
We can view this function isMultipleOf as a sort of function creator.
Definition of isMultipleOf
So now let's define this mystical function-creating function.
let isMultipleOf n x =
(x % n) = 0
Easy, huh?
If you type this into F# Interactive, it will answer:
isMultipleOf : int -> int -> bool
Where are the parenthesis?
Note that there are no parenthesis. This is not particularly important for you now. Just remember that the arrows are right associative. That is, if you have
a -> b -> c
you should interpret it as
a -> (b -> c)
The right in right associative means that you should interpret as if there were parenthesis around the rightmost operator. So:
a -> b -> c -> d
should be interpreted as
a -> (b -> (c -> d))
Usages of isMultipleOf
So, as you have seen, we can use isMultipleOf to create new functions:
let isEven = isMultipleOf 2
let isOdd = not << isEven
let isMultipleOfThree = isMultipleOf 3
let endsWithZero = isMultipleOf 10
F# Interactive would respond:
isEven : int -> bool
isOdd : int -> bool
isMultipleOfThree : int -> bool
endsWithZero : int -> bool
But you can use it differently. If you don't want to (or need to) create a new function, you can use it as follows:
isMultipleOf 10 150
This would return true, as 150 is multiple of 10. This is exactly the same as create the function endsWithZero and then applying it to the value 150.
Actually, function application is left associative, which means that the line above should be interpreted as:
(isMultipleOf 10) 150
That is, you put the parenthesis around the leftmost function application.
Now, if you can understand all this, your example (which is the canonical CreateAdder) should be trivial!
Sometime ago someone asked this question which deals with exactly the same concept, but in Javascript. In my answer I give two canonical examples (CreateAdder, CreateMultiplier) inf Javascript, that are somewhat more explicit about returning functions.
I hope this helps.
The canonical example of this is probably an "adder creator" - a function which, given a number (e.g. 3) returns another function which takes an integer and adds the first number to it.
So, for example, in pseudo-code
x = CreateAdder(3)
x(5) // returns 8
x(10) // returns 13
CreateAdder(20)(30) // returns 50
I'm not quite comfortable enough in F# to try to write it without checking it, but the C# would be something like:
public static Func<int, int> CreateAdder(int amountToAdd)
{
return x => x + amountToAdd;
}
Does that help?
EDIT: As Bruno noted, the example you've given in your question is exactly the example I've given C# code for, so the above pseudocode would become:
let x = f1 3
x 5 // Result: 8
x 10 // Result: 13
f1 20 30 // Result: 50
It's a function that takes an integer and returns a function that takes an integer and returns an integer.
This is functionally equivalent to a function that takes two integers and returns an integer. This way of treating functions that take multiple parameters is common in functional languages and makes it easy to partially apply a function on a value.
For example, assume there's an add function that takes two integers and adds them together:
let add x y = x + y
You have a list and you want to add 10 to each item. You'd partially apply add function to the value 10. It would bind one of the parameters to 10 and leaves the other argument unbound.
let list = [1;2;3;4]
let listPlusTen = List.map (add 10)
This trick makes composing functions very easy and makes them very reusable. As you can see, you don't need to write another function that adds 10 to the list items to pass it to map. You have just reused the add function.
You usually interpret this as a function that takes two integers and returns an integer.
You should read about currying.
a function taking an integer, which returns a function which takes an integer and returns an integer
The last part of that:
a function which takes an integer and returns an integer
should be rather simple, C# example:
public int Test(int takesAnInteger) { return 0; }
So we're left with
a function taking an integer, which returns (a function like the one above)
C# again:
public int Test(int takesAnInteger) { return 0; }
public int Test2(int takesAnInteger) { return 1; }
public Func<int,int> Test(int takesAnInteger) {
if(takesAnInteger == 0) {
return Test;
} else {
return Test2;
}
}
You may want to read
F# function types: fun with tuples and currying
In F# (and many other functional languages), there's a concept called curried functions. This is what you're seeing. Essentially, every function takes one argument and returns one value.
This seems a bit confusing at first, because you can write let add x y = x + y and it appears to add two arguments. But actually, the original add function only takes the argument x. When you apply it, it returns a function that takes one argument (y) and has the x value already filled in. When you then apply that function, it returns the desired integer.
This is shown in the type signature. Think of the arrow in a type signature as meaning "takes the thing on my left side and returns the thing on my right side". In the type int -> int -> int, this means that it takes an argument of type int — an integer — and returns a function of type int -> int — a function that takes an integer and returns an integer. You'll notice that this precisely matches the description of how curried functions work above.
Example:
let f b a = pown a b //f a b = a^b
is a function that takes an int (the exponent) and returns a function that raises its argument to that exponent, like
let sqr = f 2
or
let tothepowerofthree = f 3
so
sqr 5 = 25
tothepowerofthree 3 = 27
The concept is called Higher Order Function and quite common to functional programming.
Functions themselves are just another type of data. Hence you can write functions that return other functions. Of course you can still have a function that takes an int as parameter and returns something else. Combine the two and consider the following example (in python):
def mult_by(a):
def _mult_by(x):
return x*a
return mult_by
mult_by_3 = mult_by(3)
print mylt_by_3(3)
9
(sorry for using python, but i don't know f#)
There are already lots of answers here, but I'd like to offer another take. Sometimes explaining the same thing in lots of different ways helps you to 'grok' it.
I like to think of functions as "you give me something, and I'll give you something else back"
So a Func<int, string> says "you give me an int, and I'll give you a string".
I also find it easier to think in terms of 'later' : "When you give me an int, I'll give you a string". This is especially important when you see things like myfunc = x => y => x + y ("When you give curried an x, you get back something which when you give it a y will return x + y").
(By the way, I'm assuming you're familiar with C# here)
So we could express your int -> int -> int example as Func<int, Func<int, int>>.
Another way that I look at int -> int -> int is that you peel away each element from the left by providing an argument of the appropriate type. And when you have no more ->'s, you're out of 'laters' and you get a value.
(Just for fun), you can transform a function which takes all it's arguments in one go into one which takes them 'progressively' (the official term for applying them progressively is 'partial application'), this is called 'currying':
static void Main()
{
//define a simple add function
Func<int, int, int> add = (a, b) => a + b;
//curry so we can apply one parameter at a time
var curried = Curry(add);
//'build' an incrementer out of our add function
var inc = curried(1); // (var inc = Curry(add)(1) works here too)
Console.WriteLine(inc(5)); // returns 6
Console.ReadKey();
}
static Func<T, Func<T, T>> Curry<T>(Func<T, T, T> f)
{
return a => b => f(a, b);
}
Here is my 2 c. By default F# functions enable partial application or currying. This means when you define this:
let adder a b = a + b;;
You are defining a function that takes and integer and returns a function that takes an integer and returns an integer or int -> int -> int. Currying then allows you partiallly apply a function to create another function:
let twoadder = adder 2;;
//val it: int -> int
The above code predifined a to 2, so that whenever you call twoadder 3 it will simply add two to the argument.
The syntax where the function parameters are separated by space is equivalent to this lambda syntax:
let adder = fun a -> fun b -> a + b;;
Which is a more readable way to figure out that the two functions are actually chained.

Resources