Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a Map String -> Function in Scala

Tags:

map

scala

I would need to map strings to functions. I tried the following:

def a(a: Int,..) = ... 

which represents a generic function with various arguments,

then

val m: Map[String, Funcs] = Map("a"-> a)

where

 type Funcs = (Any*) => Any

but it doesn't really work.. I would like to make maps of mixed functions with a string as key.

like image 892
LowFieldTheory Avatar asked Jul 31 '14 12:07

LowFieldTheory


1 Answers

This is not easy. In fact, it's nearly impossible at runtime to do this. At compile time, there are several tricks you can use, all of them found in the library Shapeless. You don't have to use Shapeless as Miles showed in a gist wherein he explained:

trait Assoc[K] { type V ; val value: V }
def mkAssoc[V0](k: String, v: V0): Assoc[k.type] { type V = V0 } = new Assoc[k.type]{ type V = V0 }

and now at compile time you can match all the different things you need

implicit def fAssoc = mkAssoc("f", f)
implicit def gAssoc = mkAssoc("g", g)

and retrieve them as

def lookup(k: String)(implicit assoc: Assoc[k.type]): assoc.V = assoc.value

if you push these into a class like he's done with his HMap, you could do something along the lines of a Poly1:

abstract class FMapper{
  protected def mkAssoc[V0](k: String, v: V0): Assoc[k.type] { type V = V0 } = 
    new Assoc[k.type]{ type V = V0 }

  def apply(k: String)(implicit assoc: Assoc[k.type]): assoc.V = assoc.value

and create a class such as

class Mapped extends FMapper{
  implicit val f = mkAssoc("f", f)
  implicit val g = mkAssoc("g", g)

but as you can see, it starts to get ugly fast...

like image 71
wheaties Avatar answered Sep 28 '22 23:09

wheaties