[英]How can I define a type, that represents all binary or unary function taking ArgType as arguments and returning ReturnType?
我正在嘗試創建一個type
UnaryOrBinaryFunc
,它可以在概念上定義如下:
type A = ArgType => ReturnType
type B = (ArgType, ArgType) => ReturnType
type UnaryOrBinaryFunc = <Some code saying that UnaryOrBinaryFunc is either a A or a B>
在我的代碼我試圖定義UnaryOrBinaryFunc
為: type UnaryOrBinaryFunc = A with B
,它似乎是Eclipse的接受,我垂頭喪氣地沒有發現有關使用任何with
與關聯關鍵字type
在互聯網上的關鍵字。
現在,如果你想了解我為什么要這樣做的一些背景,我寫了一些看起來像我想要在我的項目中完成的東西:
sealed trait Token
case object AND extends Token
case object NOT extends Token
type ArgType
type ReturnType
type A = ArgType => ReturnType
type B = (ArgType, ArgType) => ReturnType
type UnaryOrBinaryFunc = A with B
def f: A = ???
def g: B = ???
Map[TokenType, UnaryOrBinaryFunc] (
NOT -> f,
AND -> g
)
請注意我用過???
對於f和g的定義,因為我不想打擾它們。
現在我收到以下錯誤,與我的項目相同:
type mismatch; found : TypeDecl.A (which expands to) TypeDecl.ArgType ⇒
TypeDecl.ReturnType required: TypeDecl.UnaryOrBinaryFunc (which expands to)
TypeDecl.ArgType ⇒ TypeDecl.ReturnType with (TypeDecl.ArgType,
TypeDecl.ArgType) ⇒ TypeDecl.ReturnType
我真的不知道該怎么做,任何人都知道我如何定義UnaryOrBinaryFunc
所以我不必修改我的Map
內部的內容?
非常感謝。
直接回答這個問題....
在Scala中有幾種定義副產品的方法。
最簡單,也許最好只有兩種類型是使用Either
:
type UnaryOrBinaryFunc =
Either[(ArgType, ArgType) => ReturnType, ArgType => ReturnType]
Map[TokenType, UnaryOrBinaryFunc] (
NOT -> Left(f),
AND -> Right(g)
)
您可以為Left和Right編寫一些別名,以使事物更具可讀性。
如果您使用的是Shapeless庫,則可以使用Coproducts實現此功能,如以下問題中所述:
type UnaryOrBinaryFunc =
(ArgType, ArgType) => ReturnType :+: ArgType => ReturnType
隨着平原階,它也可以使用一個技巧來創建使用implicits副產品如這里
sealed trait UnaryOrBinaryFunc
object UnaryOrBinaryFunc {
implicit object UnaryFunc extends UnaryOrBinaryFunc[ArgType => ReturnType]
implicit object BinaryFunc extends UnaryOrBinaryFunc[(ArgType, ArgType) => ReturnType]
}
處理UnaryOrBinaryFunc的每個函數都應該采用UnaryOrBinaryFunc的隱式參數,如給定的鏈接所示。
......但是,我會質疑這種復雜性是否必要。 要解決這個問題,我會做一個:
定義您的函數以獲取List
或Product
,並在運行時切換它們的長度。
type UnaryOrBinaryFunc = Seq[ArgType] => ReturnType
保持一元和二元函數分離,並使任何必須處理的函數通用。
val unaryFns = Map[TokenType, UnaryFunc] ( NOT -> f, ... ) val binaryFns = Map[TokenType, BinaryFunc] ( AND -> g, ... ) def processUnaryOrBinaryFn[T](fn: T) = { ... }
以上哪種解決方案最合適將取決於您還需要做什么:-)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.