繁体   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