Runner Bean
Runner Bean

Reputation: 5185

Scala flatMap, what are ms and e?

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

Answers (4)

RajenDharmendra
RajenDharmendra

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

Rhys Bradbury
Rhys Bradbury

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

sheff_master
sheff_master

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

justAbit
justAbit

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 Lists 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

Related Questions