gpt4 book ai didi

Scala:基于同一层次结构的另一个类型参数值限制参数

转载 作者:行者123 更新时间:2023-12-04 22:04:49 24 4
gpt4 key购买 nike

这个问题可能有点困惑,但意图是这样的:

我想将一个值限制为参数类型层次结构中的另一个值。鉴于它们都是类型,如果能强制执行与此类似的代码,那就太好了。

sealed trait Direction
case object Buy extends Direction
case object Sell extends Direction

case class Trade[D <: Direction](id: Long, itemId: Long, quantity: Int)

case class Hedge[D <: Direction, ??? -> O is D's OppositeDirection](id: Long, itemId: Long, openingTrade: Trade[D], closingTrade: Trade[O])

简而言之:
val trade1 = Trade[Buy](id = 1, itemdId = 10, quantity = 100)
val trade2 = Trade[Sell](id = 2, itemdId = 10, quantity = -100)

val validHedge = Hedge[Buy, Sell](id = 563, itemId = 10, openingTrade= trade1, closingTrade = trade2)

是有效的,但不应允许我为不正确的配对创建对冲。例如。:
val invalidHedge = Hedge[Buy, Sell](id = 563, itemId = 10, openingTrade= trade1, closingTrade = trade1)

任何建议,将不胜感激。

更新:

如果在任何时候我希望我可以在 SO 中接受多个答案,那就是这次。所有的答案都是有效的,质量很好。我将选择最能解决问题的方法和产生最易读错误的方法。所选答案具有相反的可用值(这肯定会派上用场)并且不需要隐式。它还产生最清晰的错误消息之一。类型不等式非常优雅,但是其中有一些神奇的元素,特别是它需要 2 次消歧。从代码中删除它停止工作,没有明显的原因。隐含对当然是一个很好的解决方案,它与原始问题非常相似,但不像对立那样有用且隐含自由。

感谢所有人的出色回答和快速响应。

为了完成,这里是所有返工的代码:
object NotEquality {
trait =!=[A, B]

implicit def neq[A, B] : A =!= B = null
implicit def neqAmbig1[A] : A =!= A = null
implicit def neqAmbig2[A] : A =!= A = null //Without this duplicated line, the compiler will ignore the restriction and silently fail. Why?
}

object Trades {
sealed trait Direction
case object Buy extends Direction
case object Sell extends Direction

import NotEquality._
case class Trade[D <: Direction](id: Long, itemId: Long, quantity: Int)
case class Hedge[D <: Direction, O <: Direction](id: Long, itemId: Long, openingTrade: Trade[D], closingTrade: Trade[O])(implicit ev: D =!= O)
}


object TradesNeq extends App {
import NotEquality._
import Trades._

val trade1 = Trade[Buy.type](1,10,100)
val trade2 = Trade[Sell.type](2,10,-100)

val validHedge = Hedge[Buy.type, Sell.type](id = 563, itemId = 10, openingTrade= trade1, closingTrade = trade2)

println(s"Valid Hedge: ${validHedge}")
// val invalidHedge = Hedge[Buy.type, Buy.type](563,10,trade1,trade1)
// println(s"InvalidHedge ${invalidHedge}")
}


object TradesDOImpl extends App {
sealed trait Direction
case object Buy extends Direction
case object Sell extends Direction

class TradeDirection[D <: Direction, Op <: Direction]

implicit val BuyToSell = new TradeDirection[Buy.type, Sell.type]
implicit val SellToBuy = new TradeDirection[Sell.type, Buy.type]

case class Trade[D <: Direction](id: Long, itemId: Long, quantity: Int)

case class Hedge[D <: Direction, O <: Direction](id: Long, itemId: Long, openingTrade: Trade[D], closingTrade: Trade[O])(implicit d: TradeDirection[D, O])

val trade1 = Trade[Buy.type](id = 1, itemId = 10, quantity = 100)
val trade2 = Trade[Sell.type](id = 2, itemId = 10, quantity = -100)

val validHedge = Hedge[Buy.type, Sell.type](id = 563, itemId = 10, openingTrade= trade1, closingTrade = trade2)
println(s"Valid Hedge: ${validHedge}")
val invalidHedge = Hedge[Buy.type, Buy.type](563,10,trade1,trade1)
println(s"InvalidHedge ${invalidHedge}")
}


object TradesOpposite extends App {
sealed trait Direction
abstract class OppositeDirection[D <: Direction](val opposite: D) extends Direction
abstract class Buy(opposite: Sell) extends OppositeDirection[Sell](opposite)
case object Buy extends Buy(Sell)
abstract class Sell(opposite: Buy) extends OppositeDirection[Buy](opposite)
case object Sell extends Sell(Buy)

case class Trade[D <: Direction](id: Long, itemId: Long, quantity: Int)

case class Hedge[D <: Direction, O <: OppositeDirection[D]](id: Long, itemId: Long, openingTrade: Trade[D], closingTrade: Trade[O])

val trade1 = Trade[Buy](id = 1, itemId = 10, quantity = 100)
val trade2 = Trade[Sell](id = 2, itemId = 10, quantity = -100)

val validHedge = Hedge[Buy, Sell](id = 563, itemId = 10, openingTrade= trade1, closingTrade = trade2)
println(s"Valid Hedge: ${validHedge}")
// val invalidHedge = Hedge[Buy, Buy](563,10,trade1,trade1)
// println(s"InvalidHedge ${invalidHedge}")

}

最佳答案

您可以将每个 Direction 对象的类型参数化为其相反 Direction 的类型:

trait OppositeDirection[D <: Direction] extends Direction
trait Buy extends OppositeDirection[Sell]
case object Buy extends Buy
trait Sell extends OppositeDirection[Buy]
case object Sell extends Sell

然后你可以打字检查对立面:
case class Hedge[D <: Direction, O <: OppositeDirection[D]](...)

更好的可能是让您的对象能够获得相反的对象:
abstract class OppositeDirection[D <: Direction](val opposite: D) extends Direction
abstract class Buy(opposite: Sell) extends OppositeDirection[Sell](opposite)
case object Buy extends Buy(Sell)
abstract class Sell(opposite: Buy) extends OppositeDirection[Buy](opposite)
case object Sell extends Sell(Buy)

关于Scala:基于同一层次结构的另一个类型参数值限制参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23804958/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com