-
Notifications
You must be signed in to change notification settings - Fork 9
Lambda expressions
Lambda expressions are anonymous functions that can be passed to other functions, invoked and partially applied. They are defined with the arrow notation:
let sum = (x:int y:int) -> x + y
If the lambda expression needs no arguments, the block can be omitted entirely:
let getFive = -> 5
Lambda's argument types can be omitted if they could be inferred from usage:
Enumerable::Range 1 10
|> Select x -> x + 0.5 // it is implied that x is int
|> Where y -> y < 50 // y is double because (x + 0.5) is double
|> Count ()
More specifically, argument types can be inferred when the lambda is...
- ...passed as an argument to a method, function, or constructor
- ...assigned to an existing variable, field, property or index of array / collection
- ...being explicitly cast to a delegate type
- ...used as a right operand of a function composition operator
By default, lambda expressions evaluate to Func<...>
if they return a value or Action<...>
if they don't. However, depending on usage they may be evaluated to any kind of delegate.
A particularly useful feature of lambda expressions is that they closure the scope around them. This means that a lambda can use or modify values from the scope where it was declared:
var count = 0
let arr = new [5; 4; 3; 2; 1]
Array::ForEach (x -> count = count + 1)
println "There are {0} items in an array" count
You can, for example, closure function arguments to create generators:
fun createMultiplier:Func<int, int> (x:int) -> (y:int) -> x * y
let byFive = createMultiplier 5
let twenty = byFive 4
You cannot, however, closure ref arguments. This is a limitation of the .NET framework itself.