How to write the function isFunction in scala?

后端 未结 3 1687
长发绾君心
长发绾君心 2021-01-29 02:48

How can i write a isFunction function in scala, so that this works:

def isFunction(x:Any) = /* SomeCode */

println(isFunction(isFunction _)) //true
println(isFu         


        
相关标签:
3条回答
  • 2021-01-29 03:20

    Quite ugly, but it works:

    def isFunction(x:Any) = x match {
      case _: Function0[_] => true
      case _: Function1[_, _] => true
      case _: Function2[_, _, _] => true
      ...
      case _: Function22[...] => true
      case _: PartialFunction[_, _] => true
      case _ => false
    }
    
    0 讨论(0)
  • 2021-01-29 03:28

    I am not a special fan of your solution and I agree with Daniel Sobral comment. If I had to implement it I would do that in a type safe way, through implicit conversion

    trait IsFunctionable {
      def isFunction : Boolean
    }
    
    object IsFunctionable {
    
      object IsFunction extends IsFunctionable {
        def isFunction = true
      }
    
      object IsNotFunction extends IsFunctionable {
        def isFunction = false
      }
    
      implicit def function0ToIsFunctionable[A<:Function0[_]](a:A):IsFunctionable = IsFunction
      implicit def function1ToIsFunctionable[A<:Function1[_,_]](a:A):IsFunctionable = IsFunction
      implicit def function2ToIsFunctionable[A<:Function2[_,_,_]](a:A):IsFunctionable = IsFunction
      // and so on
    
      implicit def anyToIsFunctionable[A](a:A):IsFunctionable = IsNotFunction
    }
    

    And now you can happily test in the repl:

    scala>  import IsFunctionable._
    import IsFunctionable._
    
    scala>  val a: Int => Int = _ * 2
    a: Int => Int = <function1>
    
    scala>  val b: (Int,Int) => Int = (_*_)
    b: (Int, Int) => Int = <function2>
    
    scala>  a(3)
    res0: Int = 6
    scala>  b(2,4)
    res3: Int = 8
    
    scala>  a.isFunction
    res4: Boolean = true
    
    scala>  b.isFunction
    res5: Boolean = true
    
    scala>  "Hello".isFunction
    res6: Boolean = false
    
    0 讨论(0)
  • 2021-01-29 03:37

    In scala you can view Functions as just objects that have a public apply method. I am not familiar with the new scala 2.10 reflection api, but you can always use traditional java way as:

    def isFunction(x:Any) = x.getClass.getMethods.map(_.getName).exists{name => 
      name == "apply" || name.startsWith("apply$")
    }
    
    val set = Set(1, 2)
    val str = "abc"
    val func = { _:Int=> 1 }
    val map = Map(1 -> 2)
    val tuple = 1->2
    val obj = new { def apply = 1 }
    val obj2 = new { private def apply = 2 } 
    
    assert(isFunction(set))
    assert(!isFunction(str))
    assert(isFunction(func))
    assert(isFunction(map))
    assert(!isFunction(tuple))
    assert(isFunction(obj))
    assert(!isFunction(obj2))
    
    0 讨论(0)
提交回复
热议问题