|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
|
|
|
Re: Re: [scala-user] Phantom typesOn Wed, Jul 9, 2008 at 6:26 PM, Rafael de F. Ferreira
<rafael@...> wrote: > Also, I was wondering if there is any way to remove the boilerplate > from the code. It becomes apparent when looking at the version with > abstract members (http://snippets.dzone.com/posts/show/5741). > > Leaving aside the phantom types, it is easy to define a BuilderPart > class to encapsulate each field (a thin wrapper over Option[] that > returns the builder for method chaining); the price is a little > mutable state. But when the types are added to the picture, I can't > think of a way to avoid threading them all in each builder method. > Moreover, when threading the types, I couldn't find a way to avoid > threading the values as well. The boilerplate for the values in the anonymous ScotchBuilders can be abstracted into a common parent. I also don't see anyway to avoid repeating the types. class DefaultBuilder[a,b,c](default:ScotchBuilder) extends ScotchBuilder { protected[BuilderPattern] val theBrand:Option[String] = default.theBrand; protected[BuilderPattern] val theMode:Option[Preparation] = default.theMode; protected[BuilderPattern] val theDoubleStatus:Option[Boolean] = default.theDoubleStatus; protected[BuilderPattern] val theGlass:Option[Glass] = default.theGlass; type HAS_BRAND = a; type HAS_MODE = b; type HAS_DOUBLE_STATUS = c; } def withBrand(b:String) = new DefaultBuilder[TRUE,self.HAS_MODE,self.HAS_DOUBLE_STATUS](self) { override protected[BuilderPattern] val theBrand:Option[String] = Some(b); } def withMode(m:Mode) = new DefaultBuilder[self.HAS_BRAND,TRUE,self.HAS_DOUBLE_STATUS](self) { override protected[BuilderPattern] val theMode:Option[Preparation] = Some(m); } On the other hand, while the Phantom Types are very cool, going further down the abstract member path might be more practical--- at least for the required fields: case class OrderOfScotch (val brand:String, val mode:Preparation, val glass:Option[Glass], val double:Boolean); abstract case class ScotchBuilder { self :ScotchBuilder => val theBrand:String; val theMode:Preparation; val theGlass:Option[Glass]=None; val double:Boolean; // optional fields can be like before def withGlass(g:Glass)=new ScotchBuilder{ val theBrand=self.theBrand; val theMode=self.theMode; val double=self.double; override val theGlass=Some(g); } def build=new OrderOfScotch(theBrand,theMode,theGlass,double); } def main(argv:Array[String]){ val b=new ScotchBuilder { val theBrand="Glen Ordinal"; val theMode=Neat; val double=false; } println(b); println(b.build); } -Henry Ware |
|
|
|
|
|
Re: Re: [scala-user] Phantom typesIn exchange for type safety, it looks as though you have to give up the ability to build the end result in stages. See the comment (@rob) I've just added. Please correct me if I'm wrong.
Rob
On Wed, Jul 9, 2008 at 11:26 PM, Rafael de F. Ferreira <rafael@...> wrote: Thanks for the plug. I would really appreciate if anyone has comments |
|
|
Re: Re: [scala-user] Phantom typesNo he hasn't. See my comment.
http://blog.rafaelferreira.net/2008/07/type-safe-builder-pattern-in-scala.html On Sun, Jul 13, 2008 at 8:09 AM, Rob Dickens <arctic.bob@...> wrote: In exchange for type safety, it looks as though you have to give up the ability to build the end result in stages. See the comment (@rob) I've just added. Please correct me if I'm wrong. |
|
|
Re: Re: [scala-user] Phantom typesYou are right. Well spotted.
On Sun, Jul 13, 2008 at 5:08 PM, James Iry <jamesiry@...> wrote:
|
| Free embeddable forum powered by Nabble | Forum Help |