是否可以在Scala中构建类型驱动的函数查找表?
我知道如何在Lisp/Scheme/Racket中实现这一点,但在Scala中不知道是否可以在Scala中构建类型驱动的函数查找表?,scala,reflection,types,Scala,Reflection,Types,我知道如何在Lisp/Scheme/Racket中实现这一点,但在Scala中不知道 // inputType derives from In and could be of subtype In1, In2, In3, ... // outputType derives from Out and could be of subtype Out1, Out2, Out3, ... def invokeTheRightFunction (functionName: Mystery1, i
// inputType derives from In and could be of subtype In1, In2, In3, ...
// outputType derives from Out and could be of subtype Out1, Out2, Out3, ...
def invokeTheRightFunction
(functionName: Mystery1, inputData: [subtype of In], outputType: Mystery2): Mystery3 =
{
val lookupTable =
List( Mystery4(functionName1, inputType1, outputType1),
Mystery4(functionName2, inputType2, outputType2),
...
Mystery4(functionNameN, inputTypeN, outputTypeN) )
...Mystery5...
}
基于functionName
、inputType
和outputType
的值,给定inputData
中属于特定子类型的,是否可以使用构建可查找表,以便使用inputData
调用适当的函数,并且具有lookupTable的函数返回的值具有正确的子类型Out
如果您想知道为什么我不使用match/case
,那是因为我希望库中有一些通用的[数据库处理]代码,但是使用库的代码将知道所有类型应该输入和输出什么
输入
,输出
,以及“神秘”的代码都在库中
In
和Out
和lookupTable
的子类型将位于使用库的代码中
为了更具体一点,假设我有[数据库]存储过程a
,B
,C
。我目前将这些存储过程的输入放在名为ArgsA
,ArgsB
,ArgsC
的case类中。我以RowA
,RowB
,RowC
的顺序返回答案。我希望所有或大部分错误处理都发生在库中
我现在的代码与类型规范有些重复,我正试图将类型规范整合到一个查找表中,以减少出错的机会。使用名为。首先,让我们定义一些类型:
sealed trait In
case class In1() extends In
case class In2() extends In
sealed trait Out //Mystery2
case class Out1() extends Out
case class Out2() extends Out
sealed trait Name //Mystery1
case class Name1() extends Name
case class Name2() extends Name
sealed trait Row //Mystery3
case class Row1() extends Row
case class Row2() extends Row
然后我们可以准备磁铁类型类:
sealed trait Magnet[N <: Name, I <: Int, O <: Out] {
type Result <: Row
def apply(name: N, in: I, out: O): Result
}
最后,我们可以准备invokeTheRightFunction
函数,它将隐式地要求Magnet
:
def invokeTheRightFunction[N <: Name, I <: Int, O <: Out](name: N, in: I, out: O)(implicit magnet: Magnet[N,I,O]): magnet.Result = magnet(name, in, out)
使用类型类来模拟这个“查找”怎么样?@LuisMiguelMejíaSuárez谢谢,这听起来是一个很有潜力的解决方案。我会调查的。哇,谢谢你!我会查一查,如果有用的话,我会再次感谢你!一天的工作结束了,所以我几小时后到家后会检查一下。再次感谢。我从来不知道磁铁!我以前写的和你写的差不多,但是没有丢失的磁铁。
def invokeTheRightFunction[N <: Name, I <: Int, O <: Out](name: N, in: I, out: O)(implicit magnet: Magnet[N,I,O]): magnet.Result = magnet(name, in, out)
val r1: Row1 = invokeTheRightFunction(Name1(), In1(), Out2())
val r2: Row2 = invokeTheRightFunction(Name2(), In2(), Out1())