Действительно ли это возможно к карри наоборот в Scala?

Давайте примем эту функцию:

def autoClosing(f: {def close();})(t: =>Unit) = {
    t
    f.close()
}

и этот отрывок:

val a = autoClosing(new X)(_)
a {
 println("before close")
}

действительно ли возможно приправить первую часть карри? Что-то как:

val a = autoClosing(_) { println("before close") }

так, чтобы я мог отправить объекты, на которых близко должен быть выполнен, и тот же блок выполнился на них?

5
задан sepp2k 1 March 2011 в 20:34
поделиться

3 ответа

Yes, the snippet you have given works, as long as you give the type of the placeholder character.

Therefore, the code you are looking for is:

val a = autoClosing(_: {def close();}) { println("before close") }

which compiles and works as expected :).

A couple of notes:

  • You can make your life easier if you define a type alias for an AnyRef type having a close method, something like type Closeable = AnyRef {def close()}, or an appropriate interface.
  • The code snippet autoClosing(_: Closeable){ ... } is actually equivalent to the following expanded anonymous function: c: Closeable => autoClosing(c){ ... }. The wildcard character is just shorthand for a partially applied function. You need to give the type of the _ as the type inferer unfortunately cannot infer the type in this case.

Hope it helps,

-- Flaviu Cipcigan

10
ответ дан 18 December 2019 в 08:28
поделиться

Я рад видеть, что сегодня так много людей отвечают на вопросы Scala. Однако мне труднее что-то придумать. Вот альтернатива решению Flaviu .

val a: {def close();} => Unit = autoClosing(_) { println("before close") }

Конечно, правильным решением является определение автоматического закрытия способом, совместимым с тем, как вы собираетесь его использовать.

3
ответ дан 18 December 2019 в 08:28
поделиться

В качестве альтернативы вы можете перевернуть параметры:

def flip[A1, A2, B](f: A1 => A2 => B): A2 => A1 => B = x1 => x2 => f(x2)(x1)

В вашем случае:

val a = flip(autoClosing){ println("before close") }

Изменить: Я добавил фигурные скобки, чтобы помочь синтаксическому анализатору:

def flip[A1, A2, B](f: (A1 => (A2 => B))): (A2 => (A1 => B)) = {
    x1 => (x2 => f(x2)(x1))
}

Flip преобразует функцию (A1 => (A2 => B)) в (A2 => (A1 => B) ) .

scala> def x(x1 : Int)(x2 : Long) = 1.0 * x1 / x2
x: (Int)(Long)Double

scala> val f = flip(x)
f: (Long) => (Int) => Double = <function>

scala> val g = f(1)
g: (Int) => Double = <function>

scala> val h = g(2)
h: Double = 2.0

scala> x(1)(2)
res0: Double = 0.5
6
ответ дан 18 December 2019 в 08:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: