placeybordeaux
placeybordeaux

Reputation: 2216

selecting a subset of a list of functions based off of the type of their arguments in scala

This is the code in question. Something of a description/explination is included below

object Functions {
  import scala.reflect.Manifest
  private var functions: List[(Manifest[_],Any,String)] = List()
  def add[T](desc: String,func: T)(implicit m: Manifest[T]) {
    functions ::= (m,func,desc)
  }

  def get[T]()(implicit m : Manifest[T]): List[(T,String)] = {
    functions flatMap {
      case (t,f,s) => if (t <:< m) Some(f.asInstanceOf[T],s) else None
    }
  }

  def getInputs[T]()(implicit m : Manifest[T]): List[(T => Any,String)] = {
  functions flatMap {
    case (t,f,s) => if (t <:< (T => Any)) Some(f.asInstanceOf[T => Any],s) else None
    }
  }

Basically my goal is to have a list of functions, with their types (input and output) perserved and the ability to search for specific functions based off of what they take as input and what they take as output. I am starting to believe that this is not possible in scala without some sort of a monkey patch, which I would like to avoid.

Upvotes: 2

Views: 443

Answers (1)

Miles Sabin
Miles Sabin

Reputation: 23056

You should be able to do what you want with shapeless's HLists,

Sample REPL session,

scala> import shapeless._
import shapeless._

scala> val f1 : String => Int = _.length
f1: String => Int = <function1>

scala> val f2 : Boolean => Boolean = !_
f2: Boolean => Boolean = <function1>

scala> val f3 : Int => String = "("+_+")"
f3: Int => String = <function1>

scala> val fs = f1 :: f2 :: f3 :: HNil
fs: (String => Int) :: (Boolean => Boolean) :: (Int => String) :: HNil =
  <function1> :: <function1> :: <function1> :: HNil

scala> val args = "foo" :: true :: 23 :: HNil
args: String :: Boolean :: Int :: HNil = foo :: true :: 23 :: HNil

scala> fs zipApply args
res0: Int :: Boolean :: String :: HNil = 3 :: false :: (23) :: HNil

Note that the individual types of the functions are preserved in the HList fs, that the individual types of the argument values are preserved in args, and that the types of the elements of the result of the zipApply are determined appropriately by the types of the corresponding function and argument.

Upvotes: 4

Related Questions