2015-03-13 61 views
2

Scala类型推理非常好,很容易使用,而不必写两次东西。当你需要的时候,伤害越多。一个这样的例子是函数类型。可以通过推理来定义函数类型吗?

有时我想为某些函数签名创建一个命名类型。以某种方式可能吗?有什么方法可以获得函数的编译时类型,以便在定义FType时不必再次键入它?

object Foo { 
    def f(a:Int, b:Int, x:Double, y:Double, name:String) : Unit = {} 

    //type FType = typeOf(f) // can compiler provide me a compile time type somehow? 
    type FType = (Int,Int,Double,Double,String) => Unit 

    def callF(func:FType) = func(0,0,0,0,"") 
} 

有没有像Scala中的C++ decltype可以用于此目的?

回答

2

我不太清楚你想在这里实现什么,如果我理解正确,你想避免两次输入(a:Int, b:Int, x:Double, y:Double, name:String)

那么你自己先定义FType,然后在fcallF中简单地重用它呢?

object Foo { 
    type FType = (Int,Int,Double,Double,String) => Unit 

    def f: FType = (a, b, x, y, name) =>() 

    def callF(func: FType) = func(0,0,0,0,"") 
} 

如果你真的想在抽象FType,这是一个显著不同的问题,但它似乎并不像你通过调用func(0,0,0,0,"")迫使类型的情况。

您在Scala中没有decltype,因为类型不是一流的公民,例如他们可以在Idris中。也就是说,你应该可以使用Shapeless和/或宏编写它。

如果您想修复类型和参数并重用它们,最简单的解决方案是将它们变成case class。然后,您可以使用import直接访问你的域:

object Foo { 
    case class FArgs(a: Int, b: Int, x: Double, y: Double, name: String) 

    def f(args: FArgs): Unit = { 
    import args._ 
    println(name) // or whatever you want to do 
    } 

    def callF(func: FArgs => Unit) = func(FArgs(0,0,0,0,"")) 
} 
+2

这无疑是进步,但仍然有我写这个'(A,B,X,Y,名)'这是一种重复自己的。从'f'推出'FType'可以避免这种情况,但我想这是不可能的。 – Suma 2015-03-13 15:37:02

+0

..不,我不想抽象'FType',我只是想避免在定义'f'和用于它的回调类型时重复自己。 – Suma 2015-03-13 15:46:35

+1

如果你想定义多个类型为“FType”的函数,并且你希望它们不仅是相同的类型,而且要有相同的参数名称,这是我能想到的唯一重复,那么你应该简单地定义一个案例类。像case class FArgs(a:Int,b:Int,x:Double,y:Double,name:String)' – blouerat 2015-03-13 15:56:31

相关问题