Я слышал разговор о Jeff/Joel об этом на подкасте сегодня ( эпизод 34 , 2008-12-16 (MP3, 31 МБ), 1:03:38 secs - 1:06:45 secs), и я думал, что вспомнил Stack Overflow использовал LINQ to SQL, но возможно это было угроблено. Вот то же самое в LINQ to SQL.
var inValues = new [] { "ruby","rails","scruffy","rubyonrails" };
var results = from tag in Tags
where inValues.Contains(tag.Name)
select tag;
Вот именно. И, да, LINQ уже смотрит назад достаточно, но Contains
пункт кажется дополнительным назад мне. Когда я должен был сделать подобный запрос для проекта на работе, я естественно пытался сделать это неправильный путь путем выполнения соединения между локальным массивом и таблицей SQL Server, расчета LINQ to переводчик SQL был бы достаточно умен для обработки перевода так или иначе. Это не сделало, но это действительно предоставляло сообщение об ошибке, которое было описательным и указало на меня к использованию , Содержит .
Так или иначе, если Вы выполняете это в наиболее рекомендуемом LINQPad и выполняете этот запрос, можно просмотреть фактический SQL, который генерировал SQL поставщик LINQ. Это покажет Вам каждое из значений, параметризованных в IN
пункт.
Вы можете сделать это так:
trait Forall {
def f[Z] : Z=>Z
}
def z(u : Forall) = w(u.f[Int], u.f[Double])
Или используя структурные типы:
def z(u : {def f[Z] : Z=>Z}) = w(u.f[Int], u.f[Double])
Но это будет медленнее, чем первая версия, так как она использует отражение.
РЕДАКТИРОВАТЬ: Это как использовать вторую версию:
scala> object f1 {def f[Z] : Z=>Z = x => x}
defined module f1
scala> def z(u : {def f[Z] : Z=>Z}) = (u.f[Int](0), u.f[Double](0.0))
z: (AnyRef{def f[Z]: (Z) => Z})(Int, Double)
scala> z(f1)
res0: (Int, Double) = (0,0.0)
Для первой версии добавьте f1 extends Forall
или просто
scala> z(new Forall{def f[Z] : Z=>Z = x => x})
If you're curious, what you're talking about here is called "rank-k polymorphism." See wikipedia. In your case, k = 2. Some translating:
When you write
f[X](x : X) : X = ...
then you're saying that f has type "forall X.X -> X"
What you want for z is type "(forall Z.Z -> Z) -> Unit". That extra pair of parenthesis is a big difference. In terms of the wikipedia article it puts the forall qualifier before 2 arrows instead of just 1. The type variable can't be instantiated just once and carried through, it potentially has to be instantiated to many different types. (Here "instantiation" doesn't mean object construction, it means assigning a type to a type variable for type checking).
As alexy_r's answer shows this is encodable in Scala using objects rather than straight function types, essentially using classes/traits as the parens. Although he seems to have left you hanging a bit in terms of plugging it into your original code, so here it is:
// this is your code
object TypeExample {
def main(args: Array[String]):Unit = {
def f[X](x:X):X = x // parameterize fn
def v(f:Int=>Int):Unit = { } // function that operates on an Int to Int function
v(f) // applied, types correct
v(f[Int]) // appplied, types correct
def w[Z](f:Z=>Z,g:Double=>Double):Unit = {} // function that operates on two functions
w(f[Int],f[Double]) // works
// This is new code
trait ForAll {
def g[X](x : X) : X
}
def z(forall : ForAll) = w(forall.g[Int], forall.g[Double])
z(new ForAll{def g[X](x : X) = f(x)})
}
}
Я не думаю, что то, что вы хотите делать, возможно.
Редактировать:
Моя предыдущая версия была ошибочной. Это действительно работает:
scala> def z(f: Int => Int, g: Double => Double) = w(f, g)
z: (f: (Int) => Int,g: (Double) => Double)Unit
scala> z(f, f)
Но, конечно, это в значительной степени то, что у вас есть.
Я не думаю, что это вообще возможно, потому что параметры типа существуют только во время компиляции. Во время выполнения такого нет. Так что для меня даже не имеет смысла передавать параметризованную функцию вместо функции с параметрами типа, определенными Scala.
И нет, в Scala нет макросистемы.
Во время выполнения такого нет. Так что для меня даже не имеет смысла передавать параметризованную функцию вместо функции с параметрами типа, определенными Scala.И нет, в Scala нет макросистемы.
Во время выполнения такого нет. Поэтому для меня даже не имеет смысла передавать параметризованную функцию вместо функции с параметрами типа, определенными Scala.И нет, в Scala нет макросистемы.