簡體   English   中英

如何定義一個類型,它表示將ArgType作為參數並返回ReturnType的所有二元或一元函數?

[英]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的隱式參數,如給定的鏈接所示。

......但是,我會質疑這種復雜性是否必要。 要解決這個問題,我會做一個:

  • 定義您的函數以獲取ListProduct ,並在運行時切換它們的長度。

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM