Reputation: 5185
I'm learning Scala and in the below code using flatMap (taken from 99 Scala problems) I have
def myflatten(somelist : List[Any]): List[Any] = somelist flatMap {
case ms: List[_] => flatten(ms)
case e => List(e)
}
Now Im totally confused what the 'ms' and 'e' are? they must be something key as if I change ms to say dd, I get the error "not found value ms". If I hover over them i get a tool-tip saying 'ms' is a 'List[ ][ ]' and 'e' is 'Any'.
I've tried googling for "Scala List elements ms and e" or "Scala flatMap ms and e" or "Scala what do case ms and case e mean?" but I have not seem to find anything that explains what these 'ms' and 'e' are.
Are they keywords? Where can I find info on them in the Scala documentation?
P.S. I understand the code, but just not what ms and e are
Upvotes: 5
Views: 6224
Reputation: 349
In general you are comparing with two different cases (ie) case ms having list of any and the other one is of case default specified by e. so if you have list[_] then will implement flat map or else the second option you specified
Upvotes: -1
Reputation: 1707
If you're new, let me explain step by step whats going on here.
def myflatten(somelist : List[Any]): List[Any] = somelist flatMap {
case ms: List[_] => flatten(ms)
case e => List(e)
}
Written verbosely:
def myflatten(somelist : List[Any]): List[Any] = somelist flatMap { something =>
something match {
case ms: List[_] => flatten(ms)
case e => List(e)
}
}
What is ms
and e
?
First let me break this down.
You are flatMapping over a List[Any]
.
val x = List("Str1", "Str2", "Str3")
val y = x flatMap { elementInList => List(elementInList) }
This means for each element in the list, you are creating a new List with that element in it. Because its a flatMap
you essentially get the same (same elements) list back.
Checkout what would happen if you use map
instead of flatMap
:
val x = List("Str1", "Str2", "Str3")
val y = x map { elementInList => List(elementInList) }
the val
y
would be:
List(List("Str1"), List("Str2"), List("Str3"))
check out http://www.brunton-spall.co.uk/post/2011/12/02/map-map-and-flatmap-in-scala/
now, looking at the verbose example:
def myflatten(somelist : List[Any]): List[Any] = somelist flatMap { something =>
something match {
case ms: List[_] => flatten(ms)
case e => List(e)
}
}
you are matching on the element in the list or in this case called something
.
you are also matching on the elements type
.
for example
def myMatch(e: Any): String = {
e match {
case x: String => "Its a String: " + x
case y: Int => "Its a Int: " + y
//notice how im using x twice.. its because they're in separate scope!
case x: Boolean => "Its a Boolean: " + x
case _ => "Its something else!"
}
}
invoke myMatch
with the param "hello"
and it will return "Its a String: hello"
.
invoke myMatch
with the param 1
and it will return "Its a Int: 1"
.
check out http://docs.scala-lang.org/tutorials/tour/pattern-matching.html
What is e
and ms
?
lets look at your code:
def myflatten(somelist : List[Any]): List[Any] = somelist flatMap {
case ms: List[_] => flatten(ms)
case e => List(e)
}
If the element in the list which we are currently looking at is of the type List[_]
(the same as List[Any]
), we then execute this block, flatten(ms)
.
ms
is the val
assigned to the element once matched.
If the element in the list which we are currently looking at is of the type _
or essentially default (case _ =>
) then return a List(e)
containing one element, which is the element which we were looking at.
This would always return a List[List[Any]]
. Which is then flattened to a List[Any]
.
I hope this helps,
Rhys
Upvotes: 14
Reputation: 19
ms, e - it's only variable names. You can call them as you wish.
In first case:
case ms: List[_] => flatten(ms)
you suppose that content of your list
def myflatten(somelist : List[Any])
can be matched as List[_] of any type
In second case statement:
case e => List(e)
you suppose that content of your list can be anything else.
Read official doc: http://docs.scala-lang.org/tutorials/tour/pattern-matching.html
And here some tutorial: https://kerflyn.wordpress.com/2011/02/14/playing-with-scalas-pattern-matching/ to get some background about scala pattern matching.
Upvotes: 1
Reputation: 4256
Here case ms: List[_]
is a typed matching for List
type elements. ms
is not a keyword, it's just a variable representing element of type List
.
And case e
is a variable matching, it is kind of catch all scenario. It matches for all elements which are not List
(as List
s will be matched by the first case). Again e
is also not a keyword.
For more info you can read Kinds of patterns
Upvotes: 2