Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create type aliases to specific Map types in Scala

Tags:

types

map

scala

I have a bunch of code that uses a Map[String, Float]. So I'd like to do

type DocumentVector = Map[String, Float]
...
var vec = new DocumentVector

but this does not compile. I get the message:

trait Map is abstract; cannot be instantiated
[error]       var vec = new DocumentVector

Ok, I think I understand what is going on here. Map is not a concrete class, it just produces an object via (). So I could do:

object DocumentVector { def apply() = { Map[String, Float]() } }
...
var vec = DocumentVector()

That works, though it's a bit clunky. But now I want to nest the types. I'd like to write:

type DocumentVector = Map[String, Float]
type DocumentSetVectors = Map[DocumentID, DocumentVector]

but this gives same "cannot be instantiated" problem. So I could try:

object DocumentVector { def apply() = { Map[String, Float]() } }
object DocumentSetVectors { def apply() = { Map[DocumentID, DocumentVector]() } }

but DocumentVector isn't actually a type, just an object with an apply() method, so the second line won't compile.

I feel like I'm missing something basic here...

like image 649
Jonathan Stray Avatar asked Jul 12 '12 19:07

Jonathan Stray


3 Answers

Just be specific about which kind of Map you want

scala> type DocumentVector = scala.collection.immutable.HashMap[String,Float]
defined type alias DocumentVector

scala> new DocumentVector                                                    
res0: scala.collection.immutable.HashMap[String,Float] = Map()

Unless you need the flexibility of the abstract Map type in which case there is no better solution than having a type alias separated from a factory (which could be a plain method, no need for an Object with apply).

like image 75
James Iry Avatar answered Oct 09 '22 16:10

James Iry


I agree with @missingfaktor, but I would implement it a little different, so that it feels like using a trait with a companion:

type DocumentVector = Map[String, Float]
val DocumentVector = Map[String, Float] _

// Exiting paste mode, now interpreting.

defined type alias DocumentVector
DocumentVector: (String, Float)* => scala.collection.immutable.Map[String,Float] = <function1>

scala> val x: DocumentVector = DocumentVector("" -> 2.0f)
x: DocumentVector = Map("" -> 2.0)
like image 28
drexin Avatar answered Oct 09 '22 16:10

drexin


How about plain methods?

type DocumentVector = Map[String, Float]
def newDocumentVector = Map[String, Float]()
type DocumentSetVectors = Map[DocumentID, DocumentVector]
def newDocumentSetVectors = Map[DocumentID, DocumentVector]() 
like image 3
missingfaktor Avatar answered Oct 09 '22 18:10

missingfaktor