如何在scala中编写函数isFunction?
如何在scala中编写isFunction函数,以便:如何在scala中编写函数isFunction?,scala,Scala,如何在scala中编写isFunction函数,以便: def isFunction(x:Any) = /* SomeCode */ println(isFunction(isFunction _)) //true println(isFunction("not a function")) //false 很难看,但它能起作用: def isFunction(x:Any) = x match { case _: Function0[_] => true case _: Func
def isFunction(x:Any) = /* SomeCode */
println(isFunction(isFunction _)) //true
println(isFunction("not a function")) //false
很难看,但它能起作用:
def isFunction(x:Any) = x match {
case _: Function0[_] => true
case _: Function1[_, _] => true
case _: Function2[_, _, _] => true
...
case _: Function22[...] => true
case _: PartialFunction[_, _] => true
case _ => false
}
很难看,但它能起作用:
def isFunction(x:Any) = x match {
case _: Function0[_] => true
case _: Function1[_, _] => true
case _: Function2[_, _, _] => true
...
case _: Function22[...] => true
case _: PartialFunction[_, _] => true
case _ => false
}
在scala中,您可以仅将函数视为具有公共
apply
方法的对象。我不熟悉新的scala 2.10反射api,但您可以始终使用传统的java方式:
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))
在scala中,您可以仅将函数视为具有公共
apply
方法的对象。我不熟悉新的scala 2.10反射api,但您可以始终使用传统的java方式:
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))
我不是你的解决方案的特别粉丝,我同意丹尼尔·索布拉尔的评论。如果我必须实现它,我会以类型安全的方式,通过隐式转换来实现
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
}
trait是可操作的{
def isFunction:Boolean
}
对象是可函数的{
对象IsFunction扩展了IsFunctionable{
def isFunction=true
}
对象IsNotFunction扩展IsFunctionable{
def isFunction=false
}
隐式def function0ToIsFunctionable[A Int=*2
答:Int=>Int=
scala>valb:(Int,Int)=>Int=()
b:(Int,Int)=>Int=
scala>a(3)
res0:Int=6
scala>b(2,4)
res3:Int=8
scala>a.isf函数
res4:Boolean=true
scala>b.isFunction
res5:Boolean=true
scala>“Hello”。isFunction
res6:Boolean=false
我不是您的解决方案的特别粉丝,我同意Daniel Sobral的评论。如果我必须实现它,我会通过隐式转换以类型安全的方式实现
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
}
trait是可操作的{
def isFunction:Boolean
}
对象是可函数的{
对象IsFunction扩展了IsFunctionable{
def isFunction=true
}
对象IsNotFunction扩展IsFunctionable{
def isFunction=false
}
隐式def function0ToIsFunctionable[A Int=*2
答:Int=>Int=
scala>valb:(Int,Int)=>Int=()
b:(Int,Int)=>Int=
scala>a(3)
res0:Int=6
scala>b(2,4)
res3:Int=8
scala>a.isf函数
res4:Boolean=true
scala>b.isFunction
res5:Boolean=true
scala>“Hello”。isFunction
res6:Boolean=false
顺便说一句,因为你也问过和:你有弱类型的背景吗,例如Python?一个更好的问题是,我如何避免使用以Any
为参数的方法,并描述你正在尝试做什么。如果你认为你需要这样的事情,通常你在做错事。就像旧的OO ada一样ge说:告诉,不要问。让对象担心它是什么以及它是如何工作的,正如Luigi所说,不要使用任何。我确实知道它不是“好的惯用scala”,但我正在重写scala中“小Schemer”的例子,在scheme(类似于书)和scala(类似于好的代码)“惯用语”中.Btw,既然你也问了和:你有弱类型的背景吗,例如Python?一个更好的问题是,我如何避免使用将Any
作为参数的方法,并描述你正在尝试做什么。如果你认为你需要这样的事情,通常你在做错事。正如古老的OO格言所说的那样:说,不要问。让对象担心它是什么以及它是如何做的,正如Luigi所说,不要使用任何。我确实知道它不是“好的惯用scala”,但我正在重写scala中“小Schemer”的例子,在scheme(类似于书)和scala(类似于好的代码)“惯用语”中。谢谢@pedrofurla。我还添加了PartialFunction
。谢谢@pedrofurla。我还添加了PartialFunction
。函数是对象,是的。但不是所有具有apply方法的对象都是函数。我们通常不关心对象的定义签名是什么,而是关心对象的行为。Scala本身接受具有在模式匹配中将方法作为提取器不应用。它还具有“视图边界”,这正是我所说的“视图函数为”的原因。此解决方案在概念上可能不正确(事实上,这取决于您所称的函数
)但它确实可以处理超过22个参数的情况。函数是对象,是的。但并非所有使用apply方法的对象都是函数。我们通常不关心对象的定义签名是什么,而是关心对象的行为。Scala本身将具有unapply
方法的对象作为提取器模式匹配中的代码>。它也有“视图边界”,这正是我说“视图函数为”的原因。此解决方案在概念上可能不正确(事实上,这取决于您所称的函数),但它确实能处理具有22个以上参数的情况。