Reputation: 391
scala> def nextOption = if (util.Random.nextInt > 0) Some(1) else None
nextOption: Option[Int]
scala> nextOption
res1: Option[Int] = Some(1)
scala> nextOption
res3: Option[Int] = None
Trying to learn scala, few questions following the code executed above:
1. Is the right part of nextOption definition consideret a function literal?
2. Would that change if it was defined using 'val' keyword instead of 'def'.
3. Why is nextOption type an Option[Int] and not a function? ( ()=>Option[Int] )
4. Would adding parantesses or brackets to this code change its type/value?
5. What would be the difference between nextOption and something like '() => if (......) some(1) Else None'
Upvotes: 1
Views: 346
Reputation: 48400
- Why is
nextOption
type anOption[Int]
and not a function() => Option[Int]
?
I think confusion stems from the way REPL prints method types of parameterless methods. Consider what happens if we add empty parameter list ()
scala> def nextOption() = if (util.Random.nextInt > 0) Some(1) else None
nextOption: ()Option[Int]
Note how now method type is printed as ()Option[Int]
, instead of familiar () => Option[Int]
. IMHO, it might be less confusing if REPL would print method type of parameterless methods like so
=> Option[Int]
as they are described in SLS
A special case are types of methods without any parameters. They are written here
=> T
. Parameterless methods name expressions that are re-evaluated each time the parameterless method name is referenced.
Note methods are not values and method type is just something internal to the compiler:
Method types do not exist as types of values. If a method name is used as a value, its type is implicitly converted to a corresponding function type.
We can convert method type to a function type explicitly via eta expansion
scala> nextOption _
res12: () => Option[Int] = $$Lambda$1218/528012220@37e5111b
Upvotes: 1
Reputation: 2734
Going in order:
1) No. Function literals are anonymous functions. Here you clearly assign your expression a name. As you mention later () => if (......) some(1) Else None
would be a function literal. If you do this in the REPL, you will see it literally returns a function :) Function literals don't have a name, tho you can assign them to a value/variable. You can read about it more here:
What is a function literal in Scala?
2) There wouldn't be any difference in this case. If you were to do an anonymous function, under the hood, the compiler would interpret this as an instance of Function0
. It is called the ETA Expansion This however I believe takes away your ability to specify generic types. More on the difference here
3) Scala allows to call methods with zero parameters just by name, aka you can omit the parenthesis. Thus, when you just call nextOption
, it evaluates the function and returns the result.
4) No, it wouldn't.
5) As mentioned in the first case, this indeed would be an anonymous function and you would see the function in the REPL
Upvotes: 1
Reputation: 22840
- Is the right part of nextOption definition considered a function literal?
No, that is just the method body.
A function literal is something like: (i: Int) => i + 1
- Would that change if it was defined using 'val' keyword instead of 'def'.
If you just change the def
with a val
the code would be executed just one time and you would get a value, not a method nor a function.
- Why is nextOption type an Option[Int] and not a function? ( ()=>Option[Int] )
That is not the type of nextOption
, but the type of the returned value after executing the method.
- Would adding parentheses or brackets to this code change its type/value?
Not sure what exactly do you mean with this one, please edit the question and I will edit the answer.
- What would be the difference between nextOption and something like '() => if (......) some(1) Else None'
If you do this:
val foo = () => if (util.Random.nextInt > 0) Some(1) else None
Then you effectively created a function, that you can use like this:
foo()
// res: Option[Int] = None
This may be of help: Difference between method and function in Scala
Upvotes: 5
Reputation: 3863
No, it is not a function literal, it is a method. A function literal would look like
val nextOptionF = () => if (util.Random.nextInt > 0) Some(1) else None
You can convert your method into a function by doing
val nextOptionF = nextOption _
def
to val
nextOption would become an Option[Int]
def nextOption() = if (util.Random.nextInt > 0) Some(1) else None
nextOption
res1: Option[Int] = Some(1)
Upvotes: 1