I have a question regarding two types int -> (int -> int) and (int -> int) -> int. What is the difference between these two?
I read here somewhere that the first one could be interpreted as a function that that takes an int and returns a function that takes and int and returns an int, which is the same as int ->int -> int. Is this right?
The difference between int -> (int -> int) and int -> int -> int is negligible (you would really only care if you had to interop with another language). These are curried functions which effectively take two integers and return an integer (for example, the built-in addition operator has a type along these lines).
However, both of these are very different from (int -> int) -> int, which takes a function from integers to integers and returns an integer. As others have mentioned, the only simple example of such a function would apply the given function to a specific value (e.g. fun (f:int->int) -> f 13).
Good question, I suspect that functionally there's not much difference. I spent a while fiddling around trying to work out how to even get those two signatures. (John Palmer's let fun1 i = fun j -> i + j just gives int -> int -> int for me)
let add a b = a + b // int -> int -> int
let inc a = add a // int -> (int -> int)
I couldn't think of a non-contrived example for the second signature:
let foo fn : int -> fn 1 // (int -> int) -> int
(This doesn't directly answer your question, but may give someone else something to chew on)
I dont really know F#, but it seems quite intuitive (many other language have the same notions).
Is a function taking an int, and returning a function that takes an int and returns an int
Is a function taking a function that takes an int and returns an int, and returning an int
The first would be kind of like curried function.
So lets see what implementations would look like:
first
let func1 i = fun j -> i+j
this has a signature of int -> (int -> int)
note that func1 2 3 shouldn't work
EDIT: It turns out that due to the way associativity works this is actually fine
but this is different to
let func2 i j= i+j
which has a type of int -> int -> int
here func2 1 2 is fine
the other example we can create like this:
let func4 a = a 1
this will have a signature of ('t->int) -> u picking a concrete a will work. Note that func4 1 2 will definitely not compile
Related
I would like to know how I can do the following please:-
// This is not correct
func += (inout lhs: Int, rhs: Int) -> Int {
return lhs + rhs
}
Objective Usage:- scrollTo(pageIndex: pageIndex += 1)
Your code is close, but it needs to do two things:
Add the right hand side to the left hand side
Return the new value.
Your code only returns the new value, it does not update the left hand side value. In theory, you could use this:
func += (lhs: inout Int, rhs: Int) -> Int {
lhs = lhs + rhs
return lhs
}
But there is another problem; The standard += operator has a void return type and you have defined a new operator with an Int return type.
If you try and use the += operator in a context where a void return type is acceptable (which is the normal use of this operator) the compiler will give an ambiguity error, since it can't determine which function it should use:
someIndex += 1 // This will give an ambiguity compile time error
You can address this by defining the operator using generics, where the arguments conform to AdditiveArithmetic (Thanks to #NewDev for this tip)
:
func +=<T: AdditiveArithmetic> (lhs: inout T, rhs: T) -> T {
lhs = lhs + rhs
return lhs
}
I must say, however, that this does seem like quite a lot of complexity to add, when you could simply have two lines of code; one to increment the pageIndex and then a call to the function.
I'm not sure if I understood you but, if I did i would be something like this
func nextPage(n1: Int) -> Int {
var number = n1 + 1
return number
}
In this article, this function
let adderGenerator numberToAdd = (+) numberToAdd
has this type signature
int -> (int -> int)
However, when I create this function, the inferred type signature is
int -> int -> int
Are these type signatures different?
If not, how can I annotate my adderGenerator so that it has the first type signature?
Edit 1
This is the best I could come up with so far:
type Generator = int -> (int -> int)
let adderGenerator: Generator = (+)
I don't like how it makes adderGenerator adopt a point-free style.
Edit 2
This seems to work:
let adderGenerator numberToAdd : (int -> int) = (+) numberToAdd
The type signatures are the same, the parentheses just help indicate that the body of the function results in a function being returned.
These three forms with the full type annotated are equivalent:
let adderGenerator : int -> int -> int =
(+)
let adderGenerator (numberToAdd : int) : int -> int =
(+) numberToAdd
let adderGenerator : int -> int -> int =
fun numberToAdd -> (+) numberToAdd
The first form is just an alias for + and simply reiterates its type.
The second form is a function declaration that annotates the type of the argument and return type separately.
The third form is a variable assigned an anonymous function.
Only making one argument explicit seems a bit odd to me, however. You can avoid partial application entirely by making both arguments explicit:
let adderGenerator (a : int) (b : int) : int =
(+) a b
let adderGenerator : int -> int -> int =
fun a b -> (+) a b
I am using FSI, how do I go from bool to float?
have: let sigF 1 = 1=1 gets: val sigF : int -> bool
need the function that has the signature: val sigF : int -> bool -> float -> stringĀ
can you not convert bool to float?
are there any resources on understanding signatures?, I cant find any examples where bool goes to anything else, do i need to understand "currying" better? (I am completely new to functional programming)
Unless this is a puzzle or a challenge, you can assume that i:int -> b:bool -> f:float -> string is the same as int -> bool -> float -> string. The only difference is that the former also includes names of the parameters of the function - which is just extra information that you can ignore and that does not change the meaning much.
You get the parameter names if you do something like this:
> let sigF (i:int) (b:bool) (f:float) = "";;
val sigF : i:int -> b:bool -> f:float -> string
The ingineous solution from Michael avoids naming the parameters by instead using patterns (matching against concrete values), which gives you the right signature, but also a plenty of warning because the function will fail if called with any other value as argument:
> let sigF 7 true 0.3 = "done";;
warning FS0025: Incomplete pattern matches on this expression.
For example, the value '0.0' may indicate a case not covered by the pattern(s).
warning FS0025: Incomplete pattern matches on this expression.
For example, the value 'false' may indicate a case not covered by the pattern(s).
warning FS0025: Incomplete pattern matches on this expression.
For example, the value '0' may indicate a case not covered by the pattern(s).
val sigF : int -> bool -> float -> string
Another solution that gives you the right signature, but without the warnings is to use _ pattern with a type annotation - this says that you are ignoring the argumnet, but it gives an explicit type to it:
> let sigF (_:int) (_:bool) (_:float) = "";;
val sigF : int -> bool -> float -> string
let f 7 true 0.3 = "done";;
7 true and .03 (all imply function inputs) while after the = is an output
val f : int -> bool -> float -> string
A function having the signature val sigF : int -> bool -> float -> string could be for example let sigF (i:int) (b:bool) (f:float) = "". The last in the row of -> symbols is the output, all others are inputs.
Got it from Here
The Ultimate Closure
Finally, for the ultra parsimonious there is the following, without a byte wasted.
let testEquality9 : (Int, Int) -> Bool = (==)
Functions decalred with the func keyword are just closures with names. == is an example of one such named function. It takes 2 Int arguements, and returns a Bool telling you if they're equal. Its type is (Int, Int) -> Bool
testEquality9 is a closure, with the type (Int, Int) -> Bool. To it, the closure of the == function is assigned.
It can be called like this:
testEquality9(1, 2) // false
testEquality9(1, 1) // true
The key thing to draw from this is that functions are really just closures, so they can be used everywhere closures can be used.
For example, if you wanted to sort an array of Ints, you could use:
let ints = [3, 1, 4, 2]
let sorted = ints.sort{$0 < $1}
The sort(_:) method takes a closure that's of type (Int, Int) -> Bool. Our closure {$0 < $1} takes 2 Int params, and returns a Bool. So it fits that signiture.
However, we can make this code shorter. Because the < operator's function already has type (Int, Int) -> Bool, we can write this:
let sorted = ints.sort(<)
This passes the function (named closure) < in directly, without explicitly making our own closure to wrap around it.
This is not actually a closure, it's the equality operator that compares two integers stored into a variable.
Every operator is defined using a function and that function can be assigned to a variable. There is nothing else to it.
Operator Overloading:
func == (i : Int, j: Int) -> Bool {
return i == j
}
Should be equivalent to that.
As the others said, it's the abbreviation form of:
let testEquality9: (Int, Int) -> Bool = { (a: Int, b: Int) -> Bool in return a == b }
Reading from right to left, it creates a function that compares two Ints and assigns it to the constant testEquality9.
You need to mentally separate the 3 pieces:
The constant name:
let testEquality9
The constant type (it's a function type):
(Int, Int) -> Bool
And the value assigned to the constant:
(==)
OR, the long version:
{ (a: Int, b: Int) -> Bool in return a == b }
Enjoy Swift :)
When using Injekt library in Kotlin for dependency injection:
Instead of injecting a value, sometimes I want to inject a function. So something like receiving the function by:
val function: (Int) -> Int = Injekt.get()
This seems to work ok, but not if I register more than one function with the same signature but different meaning. There doesn't appear to be a way to differentiate the functions.
Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that the idiomatic answers to commonly asked Injekt + Kotlin topics are present in SO. Other answers are also welcome, there are other styles of how to do this! Disclosure, I am the author of the Injekt library.
You are correct, the functions boil down to an internal representation of the signature, for example in this case as:
kotlin.jvm.functions.Function1<? super java.lang.Integer, ? extends java.lang.Integer>
And any function that has the same parameter and return type will have the same internal type and appear to be the same to Injekt. The following registrations are all valid and do not conflict:
// register some functions
Injekt.addSingletonFactory {
val function: (value: Int) -> Int = { value -> value + 1 }
function
}
Injekt.addSingletonFactory {
val function: (Long) -> Long = { value -> value - 1 }
function
}
Injekt.addSingletonFactory {
val function: (Long) -> String = { value -> "The long is $value" }
function
}
// inject and use the functions
val intFunction: (Int) -> Int = Injekt.get()
val intResult = intFunction(2)
val longFunction: (Long) -> Long = Injekt.get()
val longResult = longFunction(2)
val longStringFunction: (Long) -> String = Injekt.get()
val stringResult = longStringFunction(10)
If you want to use the same function signature as different meaning, you can create a class wrapper for each meaning of the function:
class Int1Action(val function: (Int) -> Int) {
operator fun invoke(i: Int): Int = function(i)
}
By adding the invoke operator, you can naturally use this wrapper without referencing the function member, such as:
Injekt.addSingletonFactory {
val function: (Int) -> Int = { value -> value + 20 }
Int1Action(function)
}
val action: Int1Action = Injekt.get()
val result = action(2) // call it directly using the invoke operator