शेपलेस में मौजूदा प्रकार के वर्गों (NatTRel
और) के साथ ऐसा करना संभव हो सकता है, लेकिन मुझे 100% यकीन नहीं है, और यह एक ऐसा मामला है जहां मैं अपना खुद का प्रकार लिखूंगा वर्ग:
import shapeless._
trait OptionalPieces[L <: HList, S <: HList] {
def apply(l: L): Option[S]
}
object OptionalPieces extends LowPriorityOptionalPieces {
implicit val hnilOptionalPieces: OptionalPieces[HNil, HNil] =
new OptionalPieces[HNil, HNil] {
def apply(l: HNil): Option[HNil] = Some(HNil)
}
implicit def hconsOptionalPiecesMatch[H, T <: HList, S <: HList](implicit
opt: OptionalPieces[T, S]
): OptionalPieces[Option[H] :: T, H :: S] =
new OptionalPieces[Option[H] :: T, H :: S] {
def apply(l: Option[H] :: T): Option[H :: S] = for {
h <- l.head
t <- opt(l.tail)
} yield h :: t
}
}
sealed class LowPriorityOptionalPieces {
implicit def hconsOptionalPiecesNoMatch[H, T <: HList, S <: HList](implicit
opt: OptionalPieces[T, S]
): OptionalPieces[Option[H] :: T, S] =
new OptionalPieces[Option[H] :: T, S] {
def apply(l: Option[H] :: T): Option[S] = opt(l.tail)
}
}
यह गवाह है कि L
कम से कमS
के तत्वों के क्रम में, Option
में लिपटे के सभी शामिल हैं, और आप उन्हें क्रम (सुरक्षित रूप से) में खोलने में एक रास्ता देती है। क्या तुम सच में अपवाद थे तो
scala> val f1 = Foo(Some(1) , None, Some(3D))
f1: Foo = Foo(Some(1),None,Some(3.0))
scala> val f2 = Foo(None, Some("foo"), None)
f2: Foo = Foo(None,Some(foo),None)
scala> val result1 = f1.to[Int :: Double :: HNil]
result1: Option[shapeless.::[Int,shapeless.::[Double,shapeless.HNil]]] = Some(1 :: 3.0 :: HNil)
scala> val result2 = f2.to[String :: HNil]
result2: Option[shapeless.::[String,shapeless.HNil]] = Some(foo :: HNil)
, तो आप सिर्फ वाक्य रचना वर्ग में .get
कह सकते हैं, लेकिन यह है कि:
हम तो इस तरह एक वाक्य रचना सहायक वर्ग को परिभाषित कर सकते हैं:
implicit class OptionalPiecesSyntax[A, R <: HList](a: A)(implicit
gen: Generic.Aux[A, R]
) {
def to[S <: HList](implicit op: OptionalPieces[gen.Repr, S]): Option[S] =
op(gen.to(a))
}
और फिर एक बुरा विचार की तरह लगता है।
आप क्या करना चाहते हैं उदा। 'f1.to [स्ट्रिंग :: एचएनआईएल] 'मामला? ऐसा करना निश्चित रूप से संभव है, लेकिन आपको यह तय करने की आवश्यकता होगी कि मामले को कैसे संभालना है जहां लापता-नस्ल केवल रनटाइम पर जाना जाता है। –
मुझे लगता है - अपवाद, लेकिन संभव वापसी विकल्प [टी <: एचएलआईस्ट] आकारहीन 'कास्ट' की तरह, और मामले में 'f1.to [स्ट्रिंग :: एचएनआईएल]' वापसी कोई नहीं – mike