- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Re: How to find the type of an Option
it is Int. it is right there is your code. it is not a type parameter.
there is no problem :)
Am 01.01.2012 18:51, schrieb Tim P:
> Is there any way to figure out what the type of an Option argument to
> a case class is?
> Does Manifest help me here? - I can't see how
>
> example:
>
> case class Product(id: String, size: Option[Int])
>
>










How to find the type of an Option
Is there any way to figure out what the type of an Option argument to
a case class is?
Does Manifest help me here? - I can't see how
example:
case class Product(id: String, size: Option[Int])
Re: How to find the type of an Option
Hi Tim,
if you need the type at compile time just write
case class Product[T](id: String, size: Option[T])
If you nedd it at run time you add a manifest argument by
case class Product[T:Manifest](id: String, size: Option[T])
which is roughly a shortcut for
case class Product[T](id: String, size: Option[T])(implicit
sizeManifest: Manifest[T])
Peter
Re: How to find the type of an Option
Ok - a bit more background
I have
trait BaseProduct {
def id: String
}
In different variants of my model I could have
case class Product(id: String, size: Option[Int]) extends BaseProduct
or
case class Product(id: String, size: Int, weight: Option[Weight])
extends BaseProduct
or
case class Product(id: String, size: Int, description:
Option[String] ...) extends BaseProduct
or any sort of other combination of things. I actually have a set of 8
or 9 types which exhibit the same behaviour. Some of them refer to
each other and it's by way of being an internal DSL to define the
different problem types.
I was hoping to write a generic xml loader that would check names of
the case class arguments and build them for me using reflection -
something like
def buildProductFromXML[T <: BaseProduct : Manifest](xml: Node) =
Validated[T]
Within any model it is important that my case class definitions are
clear and simple. They certainly don't want to be parameterised.
Now I can obviously write a non-generic loader for the things. I could
write a generic loader if I didn't use Option and if push comes to
shove I could do something like
def bulidProductFromXML[T <: BaseProduct: Manifest](xml: Node,
optTypes: Seq[Class]) - and maybe that's the best solution. I just
wanted something a little prettier, especially since some of the sub-
classes could wind up with 10+ optional arguments.
With
On Jan 1, 6:04 pm, Sonnenschein wrote:
> Hi Tim,
>
> if you need the type at compile time just write
>
> case class Product[T](id: String, size: Option[T])
>
> If you nedd it at run time you add a manifest argument by
>
> case class Product[T:Manifest](id: String, size: Option[T])
>
> which is roughly a shortcut for
>
> case class Product[T](id: String, size: Option[T])(implicit
> sizeManifest: Manifest[T])
>
> Peter
Re: Re: How to find the type of an Option
case class ProductOne(id: String, size: Option[Int])
case class ProductTwo(id: String, description: Option[String])
trait BuildFromXML[T] extends (xml.NodeSeq => Option[T]) { def apply(in: xml.NodeSeq): Option[T] }
object BuildFromXML {
implicit def buildString: BuildFromXML[String] = new BuildFromXML[String] { def apply(in: xml.NodeSeq): Option[String] = in.headOption map (_.text) }
implicit def buildInt: BuildFromXML[Int] = new BuildFromXML[Int] { def apply(in: xml.NodeSeq): Option[Int] = try { in.headOption map (_.text.toInt) } catch { case _: NumberFormatException => None } }
implicit def buildOption[A](implicit builder: BuildFromXML[A]): BuildFromXML[Option[A]] = new BuildFromXML[Option[A]] { def apply(in: xml.NodeSeq): Option[Option[A]] = Some(builder(in)) }
implicit def buildTuple2[A, B](implicit buildA: BuildFromXML[A], buildB: BuildFromXML[B]): BuildFromXML[(A, B)] = new BuildFromXML[(A, B)] { def apply(in: xml.NodeSeq): Option[(A, B)] = { for { a <- buildA(in \ "one") b <- buildB(in \ "two") } yield (a, b) } }
implicit def buildTuple3[A, B, C](implicit buildA: BuildFromXML[A], buildB: BuildFromXML[B], buildC: BuildFromXML[C]): BuildFromXML[(A, B, C)] = new BuildFromXML[(A, B, C)] { def apply(in: xml.NodeSeq): Option[(A, B, C)] = { for { a <- buildA(in \ "one") b <- buildB(in \ "two") c <- buildC(in \ "three") } yield (a, b, c) } }
def apply[T](in: xml.NodeSeq)(implicit builder: BuildFromXML[T]): Option[T] = builder(in)
def apply[A,B](fn: (A) => B, in: xml.NodeSeq)(implicit builder: BuildFromXML[A]): Option[B] = builder(in) map fn
def apply[A,B,C](fn: (A, B) => C, in: xml.NodeSeq)(implicit builder: BuildFromXML[(A, B)]): Option[C] = builder(in) map fn.tupled
def apply[A,B,C,D](fn: (A, B, C) => D, in: xml.NodeSeq)(implicit builder: BuildFromXML[(A, B, C)]): Option[D] = builder(in) map fn.tupled
}
val xml1 = <product><one>the string</one><two>45</two></product> val xml2 = <product><one>the string</one></product>val xml3 = <product></product> val xml4 = <product><one>the string</one><two>the description</two></product>
assert(BuildFromXML(ProductOne, xml1) == Some(ProductOne("the string", Some(45))))assert(BuildFromXML(ProductOne, xml2) == Some(ProductOne("the string", None))) assert(BuildFromXML(ProductOne, xml3) == None)assert(BuildFromXML(ProductTwo, xml4) == Some(ProductTwo("the string", Some("the description")))) assert(BuildFromXML(ProductOne, xml4) == Some(ProductOne("the string", None)))
--
Derek Williams
Re: Re: How to find the type of an Option
Wow :-)
Is there a limit to the maximum number of parameters I can cope with
using this technique? Some of my records go past the length of normal
tuples. Do I hit something before the case class limit of 21 or
whatever it is?
Tim
On 1 January 2012 20:21, Derek Williams wrote:
> How about this (no reflection required):
>
> case class ProductOne(id: String, size: Option[Int])
>
> case class ProductTwo(id: String, description: Option[String])
>
> trait BuildFromXML[T] extends (xml.NodeSeq => Option[T]) { def apply(in:
> xml.NodeSeq): Option[T] }
>
> object BuildFromXML {
>
> implicit def buildString: BuildFromXML[String] = new BuildFromXML[String]
> {
> def apply(in: xml.NodeSeq): Option[String] = in.headOption map (_.text)
> }
>
> implicit def buildInt: BuildFromXML[Int] = new BuildFromXML[Int] {
> def apply(in: xml.NodeSeq): Option[Int] = try { in.headOption map
> (_.text.toInt) } catch { case _: NumberFormatException => None }
> }
>
> implicit def buildOption[A](implicit builder: BuildFromXML[A]):
> BuildFromXML[Option[A]] = new BuildFromXML[Option[A]] {
> def apply(in: xml.NodeSeq): Option[Option[A]] = Some(builder(in))
> }
>
> implicit def buildTuple2[A, B](implicit buildA: BuildFromXML[A], buildB:
> BuildFromXML[B]): BuildFromXML[(A, B)] = new BuildFromXML[(A, B)] {
> def apply(in: xml.NodeSeq): Option[(A, B)] = {
> for {
> a <- buildA(in \ "one")
> b <- buildB(in \ "two")
> } yield (a, b)
> }
> }
>
> implicit def buildTuple3[A, B, C](implicit buildA: BuildFromXML[A],
> buildB: BuildFromXML[B], buildC: BuildFromXML[C]): BuildFromXML[(A, B, C)] =
> new BuildFromXML[(A, B, C)] {
> def apply(in: xml.NodeSeq): Option[(A, B, C)] = {
> for {
> a <- buildA(in \ "one")
> b <- buildB(in \ "two")
> c <- buildC(in \ "three")
> } yield (a, b, c)
> }
> }
>
> def apply[T](in: xml.NodeSeq)(implicit builder: BuildFromXML[T]):
> Option[T] = builder(in)
>
> def apply[A,B](fn: (A) => B, in: xml.NodeSeq)(implicit builder:
> BuildFromXML[A]): Option[B] = builder(in) map fn
>
> def apply[A,B,C](fn: (A, B) => C, in: xml.NodeSeq)(implicit builder:
> BuildFromXML[(A, B)]): Option[C] = builder(in) map fn.tupled
>
> def apply[A,B,C,D](fn: (A, B, C) => D, in: xml.NodeSeq)(implicit builder:
> BuildFromXML[(A, B, C)]): Option[D] = builder(in) map fn.tupled
>
> }
>
> val xml1 = the string45
> val xml2 = the string
> val xml3 =
> val xml4 = the stringthe
> description
>
> assert(BuildFromXML(ProductOne, xml1) == Some(ProductOne("the string",
> Some(45))))
> assert(BuildFromXML(ProductOne, xml2) == Some(ProductOne("the string",
> None)))
> assert(BuildFromXML(ProductOne, xml3) == None)
> assert(BuildFromXML(ProductTwo, xml4) == Some(ProductTwo("the string",
> Some("the description"))))
> assert(BuildFromXML(ProductOne, xml4) == Some(ProductOne("the string",
> None)))
>
>
>
> --
> Derek Williams
>
Re: How to find the type of an Option
Hi Tim,
I think you would need than an HList implementation. Miles Sabin has
one in his shapeless project: https://github.com/milessabin/shapeless
Hth Andreas
On Jan 2, 10:23 am, Tim Pigden wrote:
> Wow :-)
> Is there a limit to the maximum number of parameters I can cope with
> using this technique? Some of my records go past the length of normal
> tuples. Do I hit something before the case class limit of 21 or
> whatever it is?
>
> Tim
>
> On 1 January 2012 20:21, Derek Williams wrote:
>
>
>
>
>
> > How about this (no reflection required):
>
> > case class ProductOne(id: String, size: Option[Int])
>
> > case class ProductTwo(id: String, description: Option[String])
>
> > trait BuildFromXML[T] extends (xml.NodeSeq => Option[T]) { def apply(in:
> > xml.NodeSeq): Option[T] }
>
> > object BuildFromXML {
>
> > implicit def buildString: BuildFromXML[String] = new BuildFromXML[String]
> > {
> > def apply(in: xml.NodeSeq): Option[String] = in.headOption map (_.text)
> > }
>
> > implicit def buildInt: BuildFromXML[Int] = new BuildFromXML[Int] {
> > def apply(in: xml.NodeSeq): Option[Int] = try { in.headOption map
> > (_.text.toInt) } catch { case _: NumberFormatException => None }
> > }
>
> > implicit def buildOption[A](implicit builder: BuildFromXML[A]):
> > BuildFromXML[Option[A]] = new BuildFromXML[Option[A]] {
> > def apply(in: xml.NodeSeq): Option[Option[A]] = Some(builder(in))
> > }
>
> > implicit def buildTuple2[A, B](implicit buildA: BuildFromXML[A], buildB:
> > BuildFromXML[B]): BuildFromXML[(A, B)] = new BuildFromXML[(A, B)] {
> > def apply(in: xml.NodeSeq): Option[(A, B)] = {
> > for {
> > a <- buildA(in \ "one")
> > b <- buildB(in \ "two")
> > } yield (a, b)
> > }
> > }
>
> > implicit def buildTuple3[A, B, C](implicit buildA: BuildFromXML[A],
> > buildB: BuildFromXML[B], buildC: BuildFromXML[C]): BuildFromXML[(A, B, C)] =
> > new BuildFromXML[(A, B, C)] {
> > def apply(in: xml.NodeSeq): Option[(A, B, C)] = {
> > for {
> > a <- buildA(in \ "one")
> > b <- buildB(in \ "two")
> > c <- buildC(in \ "three")
> > } yield (a, b, c)
> > }
> > }
>
> > def apply[T](in: xml.NodeSeq)(implicit builder: BuildFromXML[T]):
> > Option[T] = builder(in)
>
> > def apply[A,B](fn: (A) => B, in: xml.NodeSeq)(implicit builder:
> > BuildFromXML[A]): Option[B] = builder(in) map fn
>
> > def apply[A,B,C](fn: (A, B) => C, in: xml.NodeSeq)(implicit builder:
> > BuildFromXML[(A, B)]): Option[C] = builder(in) map fn.tupled
>
> > def apply[A,B,C,D](fn: (A, B, C) => D, in: xml.NodeSeq)(implicit builder:
> > BuildFromXML[(A, B, C)]): Option[D] = builder(in) map fn.tupled
>
> > }
>
> > val xml1 = the string45
> > val xml2 = the string
> > val xml3 =
> > val xml4 = the stringthe
> > description
>
> > assert(BuildFromXML(ProductOne, xml1) == Some(ProductOne("the string",
> > Some(45))))
> > assert(BuildFromXML(ProductOne, xml2) == Some(ProductOne("the string",
> > None)))
> > assert(BuildFromXML(ProductOne, xml3) == None)
> > assert(BuildFromXML(ProductTwo, xml4) == Some(ProductTwo("the string",
> > Some("the description"))))
> > assert(BuildFromXML(ProductOne, xml4) == Some(ProductOne("the string",
> > None)))
>
> > --
> > Derek Williams
>
> --
> Tim Pigden
> Optrak Distribution Software Limited+44 (0)1992 517100http://www.linkedin.com/in/timpigdenhttp://optrak.com
> Optrak Distribution Software Ltd is a limited company registered in
> England and Wales.
> Company Registration No.2327613Registered Offices: Orland House,
> Mead Lane, Hertford, SG13 7AT England
> This email and any attachments to it may be confidential and are
> intended solely for the use of the individual to whom it is addressed.
> Any views or opinions expressed are solely those of the author and do
> not necessarily represent those of Optrak Distribution Software Ltd.
> If you are not the intended recipient of this email, you must neither
> take any action based upon its contents, nor copy or show it to
> anyone. Please contact the sender if you believe you have received
> this email in error.
Re: Re: How to find the type of an Option
This of course doesn't work well if your case classes contain other case classes. In that case you would need to use reflection.
--
Derek Williams
Re: Re: How to find the type of an Option
case class Product(id: String, size: Option[Int]) extends BaseProduct
or
case class Product(id: String, size: Int, weight: Option[Weight])
extends BaseProduct
or
case class Product(id: String, size: Int, description:
Option[String] ...) extends BaseProduct
i am missing something. how can you declare the same case class several
times?
or is it actually just one, and the option's type can change? if so, as
suggested:
case class Product[A:Manifest](....x:Option[A])
Am 01.01.2012 19:49, schrieb Tim P:
> case class Product(id: String, size: Option[Int]) extends BaseProduct
>
> or
> case class Product(id: String, size: Int, weight: Option[Weight])
> extends BaseProduct
> or
> case class Product(id: String, size: Int, description:
> Option[String] ...) extends BaseProduct
Re: Re: How to find the type of an Option
I have different objects/packages corresponding to different models.
The case classes are defined within them.
On 1 January 2012 19:09, HamsterofDeath wrote:
> case class Product(id: String, size: Option[Int]) extends BaseProduct
>
> or
> case class Product(id: String, size: Int, weight: Option[Weight])
> extends BaseProduct
> or
> case class Product(id: String, size: Int, description:
> Option[String] ...) extends BaseProduct
>
>
>
> i am missing something. how can you declare the same case class several
> times?
> or is it actually just one, and the option's type can change? if so, as
> suggested:
>
> case class Product[A:Manifest](....x:Option[A])
>
> Am 01.01.2012 19:49, schrieb Tim P:
>> case class Product(id: String, size: Option[Int]) extends BaseProduct
>>
>> or
>> case class Product(id: String, size: Int, weight: Option[Weight])
>> extends BaseProduct
>> or
>> case class Product(id: String, size: Int, description:
>> Option[String] ...) extends BaseProduct
>