【问题标题】:Scala: Pass curried function as parameterScala:将咖喱函数作为参数传递
【发布时间】:2013-10-27 01:49:58
【问题描述】:

是否可以执行以下操作?

def takeCurriedFnAsArg(f: (Int)(implicit MyClass) => Result)

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    是的,有可能。

    当您将第二个 curried 参数标记为 implicit 时,该函数似乎 不是 类型

    Int => (MyClass => Result) => ResultOfFunction 
    

    如果柯里化的高阶函数参数是常规参数,那将是什么;相反,它看起来像这样:

    Int => ResultOfFunction
    

    这是一个简单的例子:

    scala> def curriedFn(i : Int)(implicit func : String => Int) : Boolean = (i + func("test!")) % 2 == 0
    curriedFn: (i: Int)(implicit func: String => Int)Boolean
    
    scala> implicit val fn : String => Int = s => s.length
    fn: String => Int = <function1>
    
    scala> curriedFn _
    res4: Int => Boolean = <function1>
    

    如您所见,implicit 参数已被“消除”。为什么以及如何?对于比我知识渊博的人来说,这是一个问题。如果我不得不猜测,我会说编译器直接将参数替换为隐式值,但这很可能是错误的。

    无论如何,撇开题外话不谈,这里有一个与您的情况非常相关的示例:

    scala> def foo(func : Int => Boolean) = if(func(3)) "True!" else "False!"
    foo: (func: Int => Boolean)String
    
    scala> foo(curriedFn)
    res2: String = True!
    

    现在如果第二个函数参数不是隐式的:

    scala> def curriedNonImplicit(i : Int)(fn : String => Int) : Boolean = (i + fn("test!")) % 2 == 0
    curriedNonImplicit: (i: Int)(fn: String => Int)Boolean
    
    scala> curriedNonImplicit _
    res5: Int => ((String => Int) => Boolean) = <function1>
    

    如您所见,函数的类型有点不同。这意味着解决方案看起来也会有所不同:

    scala> def baz(func : Int => (String => Int) => Boolean) = if(func(3)(s => s.length)) "True!" else "False!"
    baz: (func: Int => ((String => Int) => Boolean))String
    
    scala> baz(curriedNonImplicit)
    res6: String = True!
    

    您必须直接在方法内指定函数,因为之前没有隐式提供。

    【讨论】:

    • 感谢您用详尽的例子解释这两种情况(有和没有隐式)。
    猜你喜欢
    • 2011-04-21
    • 2013-08-26
    • 2016-10-20
    • 2014-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多