[英]How can I define a type, that represents all binary or unary function taking ArgType as arguments and returning ReturnType?
I'm trying to create a type
UnaryOrBinaryFunc
, that could conceptually be defined like this: 我正在尝试创建一个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>
in my code I tried to define UnaryOrBinaryFunc
as: type UnaryOrBinaryFunc = A with B
and it seemed to be acceptable for Eclipse, I sadly didn't find anything about using the with
keyword in association with the type
keyword on the Internet. 在我的代码我试图定义UnaryOrBinaryFunc
为: type UnaryOrBinaryFunc = A with B
,它似乎是Eclipse的接受,我垂头丧气地没有发现有关使用任何with
与关联关键字type
在互联网上的关键字。
Now if you want a little bit of context on why I want to do that, I wrote something that looks like what I want to accomplish inside my project: 现在,如果你想了解我为什么要这样做的一些背景,我写了一些看起来像我想要在我的项目中完成的东西:
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
)
Notice that I used ???
请注意我用过???
for the definitions of f and g because I didn't want to bother defining them. 对于f和g的定义,因为我不想打扰它们。
Now I get the following error, the same as in my project: 现在我收到以下错误,与我的项目相同:
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
I really don't know how to do that, anyone has an idea of how I could define UnaryOrBinaryFunc
so I don't have to modify what is inside my Map
? 我真的不知道该怎么做,任何人都知道我如何定义UnaryOrBinaryFunc
所以我不必修改我的Map
内部的内容?
Many thanks. 非常感谢。
To answer the question directly.... 直接回答这个问题....
There are several ways of defining a coproduct in Scala. 在Scala中有几种定义副产品的方法。
The simplest, and probably the best with just two types is to use Either
: 最简单,也许最好只有两种类型是使用Either
:
type UnaryOrBinaryFunc =
Either[(ArgType, ArgType) => ReturnType, ArgType => ReturnType]
Map[TokenType, UnaryOrBinaryFunc] (
NOT -> Left(f),
AND -> Right(g)
)
You can write some aliases for Left and Right to make things more readable. 您可以为Left和Right编写一些别名,以使事物更具可读性。
If you are using the Shapeless library, you can implement this with Coproducts as explained in this question: 如果您使用的是Shapeless库,则可以使用Coproducts实现此功能,如以下问题中所述:
type UnaryOrBinaryFunc =
(ArgType, ArgType) => ReturnType :+: ArgType => ReturnType
With plain scala, it's also possible to use a trick to create coproducts using implicits as shown here 随着平原阶,它也可以使用一个技巧来创建使用implicits副产品如这里
sealed trait UnaryOrBinaryFunc
object UnaryOrBinaryFunc {
implicit object UnaryFunc extends UnaryOrBinaryFunc[ArgType => ReturnType]
implicit object BinaryFunc extends UnaryOrBinaryFunc[(ArgType, ArgType) => ReturnType]
}
Every function that processes UnaryOrBinaryFunc should take an implicit parameter of UnaryOrBinaryFunc as shown in the link given. 处理UnaryOrBinaryFunc的每个函数都应该采用UnaryOrBinaryFunc的隐式参数,如给定的链接所示。
... However, I would question whether this complexity is necessary. ......但是,我会质疑这种复杂性是否必要。 To solve this problem I would do one of: 要解决这个问题,我会做一个:
Define your functions to take List
s or Product
s, and switch on their lengths at runtime. 定义您的函数以获取List
或Product
,并在运行时切换它们的长度。
type UnaryOrBinaryFunc = Seq[ArgType] => ReturnType
Keep Unary and Binary functions separate, and make generic any functions that must process either. 保持一元和二元函数分离,并使任何必须处理的函数通用。
val unaryFns = Map[TokenType, UnaryFunc] ( NOT -> f, ... ) val binaryFns = Map[TokenType, BinaryFunc] ( AND -> g, ... ) def processUnaryOrBinaryFn[T](fn: T) = { ... }
Which of all the above solutions is most appropriate will depend on what else you need to do :-). 以上哪种解决方案最合适将取决于您还需要做什么:-)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.