簡體   English   中英

如何將類聲明為具有隱式參數的擴展函數

[英]How to declare a class as extending a function with implicit parameters

我想定義一個采用一個顯式參數和一個隱式參數的函數,如下所示:

def foo(a: Int)(implicit b: Int) : Int

但作為一個類或對象,像這樣

object Foo extends ((Int,Int) => Int) {
  def apply(a: Int)(implicit b: Int) : Int = { ... }
}

這樣就可以像下面這樣調用該函數:

implicit val b = 2
val g = Foo(1)

我無法獲得Foo類應該從其正確擴展的基礎的聲明。 如何才能做到這一點?

你不能。 Function2 [T1,T2,R]聲明了抽象方法apply(t1:T1,t2:T2):R ,因此,如果要混入Function2 ,則必須實現此arity-2 apply方法,該方法具有不同的簽名而不是您要使用的咖喱版本。

因此,此問題分為兩部分-首先,如何創建一個使用咖喱參數列表實現函數的對象。 然后,如何使這些參數列表之一成為隱式。

首先肯定是有可能的。 注意,咖喱函數是返回函數的函數。 所以f(x: Int)(y: Int)實際上是Function1 ,而不是Function2

scala> def f(x: Int)(y: Int) = x + y
f: (x: Int)(y: Int)Int

scala> f _
res0: Int => Int => Int = <function1>

您當然可以創建一個實現此目的的類:

scala> object Foo extends (Int => Int => Int) {
     |   def apply(x: Int) = {(y: Int) => x + y}
     | }
defined module Foo

scala> Foo(1)(2)
res1: Int = 3

不幸的是,我不知道有什么方法可以使第二個參數列表隱式化。

除了擴展(Int, Int) => Int您還可以使用隱式轉換:

class Foo(f: (Int, Int) => Int) {
  def apply(a: Int)(implicit b: Int) : Int = f(a, b)
}

implicit def Foo_to_Function2(foo: Foo) = (x: Int, y: Int) => foo(x)(y)

測試:

val foo = new Foo(_ * 10 + _)
foo(4) //error since no implicit Int yet
{
  implicit val impint = 5
  foo(4)  //45
}  
def takesF2(f: (Int, Int) => Int) = f(1, 2)
takesF2(foo)  //12 - works as normal Function2

一個問題是:為什么您必須將那個對象Foo傳遞給“期望(Int,Int)=> Int的地方”?

我想對象Foo應該具有更多特殊功能,這些功能除了可以作為功能外還可以發揮作用嗎?

似乎最好在這里將兩個問題分開:a)函數(Int)(隱式Int)=> Int和b)對象Foo

object Foo {
  def apply(a: Int, b: Int) : Int = { ... }
}

def foo(a: Int)(implicit b: Int) : Int = Foo(a, b)

implicit val m:Int = 42

foo(5)  // --> res1: Int = 47

如果願意,您可以將'foo'視為“伴隨功能” ...

除此之外:我想嘗試應用(Int)(隱式Int)=> Int“其中(Int,Int)=> Int預期為Int”可能不起作用,因為這些類型不相同。 至少當您嘗試將其放入

def bar(f:(Int,Int)=>Int) = ....

方法欄無論如何都將使用兩個參數調用其參數f,因為它希望它接受兩個參數,並且不能假定f中提供的函數確實能夠使用隱式函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM