简体   繁体   English

如何定义一个类型,它表示将ArgType作为参数并返回ReturnType的所有二元或一元函数?

[英]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. 定义您的函数以获取ListProduct ,并在运行时切换它们的长度。

     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.

相关问题 如何在Haskell中定义代表单位类型的类型? - How to define a type that represents a Unit type in Haskell? 如何定义一个返回类型基于Scala中参数类型和类型参数的方法? - How to define a method for which the returntype is based on types of argument and type parameter in Scala? 如何定义一个函数来接受所有扩展公共基类型的类型(Scala,下面的特定代码)? - How can I define a function to accept all the types which extend a common base type (Scala, specific code below)? 如何在scala中定义递归函数类型? - How can I define a recursive function type in scala? 如何使用未定义数量和参数类型定义Scala函数 - How to define scala function with undefined number and type of arguments 如何在Scala中定义类型类的实例,该实例可用于特定类型的所有子类? - How can I define an instance of a typeclass in scala that can be used for all subclasses of a particular type? 如何从Java调用带有PartialFunction且具有Unit返回类型的Scala函数? - How can I call a Scala function taking a PartialFunction with a Unit return type from Java? 代表带有名字参数的函数的FunctionN特性是什么? - What is the FunctionN trait that represents a function taking a by-name parameter? 如何创建ConfigValue表示Typesafe.Config中的对象 - How can I create a ConfigValue represents a object in Typesafe.Config 如何为 function 类型定义 Monad? - How to define a Monad for a function type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM