3

我知道我可以做instanceOf檢查針對Function1Function2等,但有沒有一種通用的方法來查看是否有功能或不是功能(它可以有任意數量的參數)。我試圖定義這樣的事情:什麼是Scala中所有函數的超類型?

type FuncType = (Any*) -> Any 

但是,這也沒有工作。基本上我有一些看起來像這樣的代碼:

call = (name: Any, args: Any*) -> if name.isFunction then name.castAs[Function].apply(args) else name 
aFunction = (name: String) => "Hello " + name 
notAFunction = "Hello rick" 
call(aFunction, "rick") 
call(notAFunction) 

回答

3

沒有,有沒有辦法做到這一點,除了要經過檢查每個Function1Function2等這些性狀的母公司爲AnyRef,這將不利於你對他們從別的區別。這些特徵中的每一個的apply方法都需要不同數量的參數,因此無法爲它們提供具有應用方法的父項。你也許可以得到你正在嘗試做的最接近的是:

def arbitraryFunction(function: AnyRef, args: Seq[Any]): Any = { 
    function match { 
    case f: Function1[Any, Any] => f(args(0)) 
    case f: Function2[Any, Any, Any] => f(args(0), args(1)) 
    // and so on 
    } 
} 

但是,這是瘋狂和危險的,會在運行時拋出異常,如果類型錯誤,例如

arbitraryFunction((x: Int) => x * 2, List("I'm a String!")) 
4

沒有所有函數類型的通用超類型。

Scala沒有辦法對函數的arity進行抽象。但是,您可以查看Shapeless庫,該庫引入了一個名爲HList的函數,您可以使用它來抽象函數的形式。

但是,我想這不是你真正需要的。這聽起來像你只是想做一個檢查,如「這是一個功能?」你可能會認爲奇怪的是沒有任何arity-agnostic Function超類型,但是如果你想對它做一些有用的事情,你幾乎總是需要知道函數的arity。

或者,您可能可以使用該函數的curried方法執行某些操作,該方法將返回Function1

相關問題