Reputation: 53786
I've encountered this scala code and I'm trying to work out what its doing except the fact it returns an int. I'm unsure of these three lines :
l match {
case h :: t =>
case _ => 0
Function :
def iterate(l: List[Int]): Int =
l match {
case h :: t =>
if (h > n) 0
case _ => 0
}
Upvotes: 0
Views: 1996
Reputation: 7320
First, you define a function called iterate
and you specified the return type as Int
. It has arity 1, parameter l
of type List[Int]
.
The List
type is prominent throughout functional programming, and it's main characteristics being that it has efficient prepend and that it is easy to decompose any List
into a head and tail. The head would be the first element of the list (if non-empty) and the tail would be the rest of the List
(which itself is a List
) - this becomes useful for recursive functions that operate on List
.
The match
is called pattern matching.. it's essentially a switch
statement in the C-ish languages, but much more powerful - the switch
restricts you to constants (at least in C it does), but there is no such restriction with match
.
Now, your first case
you have h :: t
- the ::
is called a "cons", another term from functional programming. When you create a new List
from another List
via a prepend, you can use the ::
operator to do it.
Example:
val oldList = List(1, 2, 3)
val newList = 0 :: oldList // newList == List(0, 1, 2, 3)
In Scala, operators that end with a :
are really a method of the right hand side, so 0 :: oldList
is the equivalent of oldList.::(0)
- the 0 :: oldList
is syntactic sugar that makes it easier to read.
We could've defined oldList
like
val oldList = 1 :: 2 :: 3 :: Nil
where Nil
represents an empty List
. Breaking this down into steps:
3 :: Nil
is evaluated first, creating the equivalent of a List(3)
which has head 3 and empty tail.List(3)
.List(2, 3)
.The resulting List
of List(1, 2, 3)
is assigned to the val oldList
.
Now when you use ::
to pattern match you essentially decompose a List
into a head and tail, like the reverse of how we created the List
above. Here when you do
l match {
case h :: t => ...
}
you are saying decompose l
into a head and tail if possible. If you decompose successfully, you can then use these h
and t
variables to do whatever you want.. typically you would do something like act on h
and call the recursive function on t
.
One thing to note here is that your code will not compile.. you do an if (h > n) 0
but there is no explicit else
so what happens is your code looks like this to the compiler:
if (h > n) 0
else { }
which has type AnyVal
(the common supertype of 0
and "nothing"), a violation of your Int
guarentee - you're going to have to add an else
branch with some failure value or something.
The second case _ =>
is like a default
in the switch
, it catches anything that failed the head/tail decomposition in your first case
.
Your code essentially does this:
l
List
parameter and see if it can be decomposed into a head and tail.n
. If it is greater than n
, the function returns 0. (You need to add what happens if it's not greater)Upvotes: 16
Reputation: 11686
This is called pattern matching. It's like a switch
statement, but more powerful.
Some useful resources:
http://www.scala-lang.org/node/120
http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-4
Upvotes: 1