Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala flatMap, what are ms and e?

Tags:

list

scala

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

like image 798
Runner Bean Avatar asked May 20 '16 07:05

Runner Bean


1 Answers

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

like image 190
Rhys Bradbury Avatar answered Nov 15 '22 07:11

Rhys Bradbury