[英]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.