<div dir="ltr"><div><div><div>@Theodore, thank you for the working example.<br><br></div>You
 did simplify the problem statement. Actually Basket itself is a more 
complicated structure, with Item being one of its attributes. But, let 
me go along with your simplification. <br><br></div>It seems to me that,
 your approach replaces placeholder "error" expression I had, with a 
no-op on the Right value.  Of course, I could switch the right function 
to 'either' to do some thing more than a no-op.  Is that correct?<br><br></div><div>@Imants,
 @Matthias : I agree with your suggestions and that is where @Theodore's
 approach was also leading to but in a different form.<br><br><br></div><div>Looks
 like unless I have 2 separate entities, one for Frozen and one for  
Flexible, I will have to deal with run-time behaviour. I say this, since
 in a more complicated scenario, I might want to map over a list of 
buckets,. but only be able to called updated on items in the list that 
are of particular type.<br><br></div><div>Thanks<br></div><div>Guru<br></div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jul 30, 2016 at 5:55 PM, Theodore Lief Gannon <span dir="ltr"><<a href="mailto:tanuki@gmail.com" target="_blank">tanuki@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">(Apologies for any duplicates... for some reason the original's reply address is <a href="mailto:haskell-cafe@googlegroups.com" target="_blank">haskell-cafe@googlegroups.com</a> rather than <a href="mailto:haskell-cafe@haskell.org" target="_blank">haskell-cafe@haskell.org</a>, and it sent a rejection notice for my reply.)<span class=""><div><br></div><div><div dir="ltr" style="font-size:12.8px">If I understand your model right, the Item is just a count, and it's the Basket's 'name' field which actually says what the item is? Assuming I have that right, check this out:<div><br></div><div><div>-- A basket is the association of an item with a count.</div><div>data Basket = Basket {item :: String, count :: Int}</div><div><br></div><div>-- Open and closed baskets are just baskets with different behavior.</div><div>newtype OpenBasket = OpenBasket {getOpenBasket :: Basket}</div><div>newtype ClosedBasket = ClosedBasket {getClosedBasket :: Basket}</div><div><br></div><div>-- A cart can contain a mix of both basket types.</div><div>type CartBasket = Either OpenBasket ClosedBasket</div><div>data Cart = List CartBasket</div><div><br></div><div>-- We'll want to conveniently inspect CartBaskets.</div><div>getCartBasket :: CartBasket -> Basket</div><div>getCartBasket = either getOpenBasket getClosedBasket</div><div><br></div><div>-- This function accepts only OpenBaskets. No need for a runtime check.</div><div>addToOpenBasket :: OpenBasket -> OpenBasket</div><div>addToOpenBasket (OpenBasket b@(Basket _ i))</div><div>  = OpenBasket (b {count = i+1})</div><div><br></div><div>-- First-class functions let you keep this safety all the way to the top...</div><div>data UserControl a = UserControl {label :: String, behavior :: a -> a}</div><div><br></div><div>-- Only allow the user to see valid behaviors!</div><div>getAddToCartBasketUserControl :: CartBasket -> UserControl CartBasket<br></div><div>getAddToCartBasketUserControl =</div><div>  let f = either (Left . addToOpenBasket) Right</div><div>  in either (const (UserControl "Add" f)) (const (UserControl "Locked" f))</div></div><div><br></div></div></div></span></div><div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Sat, Jul 30, 2016 at 3:01 PM, Gurudev Devanla <span dir="ltr"><<a href="mailto:gurudev.devanla@gmail.com" target="_blank">gurudev.devanla@gmail.com</a>></span> wrote:<br></span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr">Hello All,<br><br>I have a design question where I could use some of your thoughts and suggestions. Here is the setup. I apologize<br>for the long email but I have resisted asking this question, since it needs a long explanation, until now.<br><br>I have a set of data structures defined as follows<br><br>--  An Item that can be of two types,  one whose value can be changed, one whose value are frozen once created  <br>data Item = FreeToChange {freeToChangeCount:: Int}<br>  | CannotChange {frozenCount:: Int}<br><br>-- The item is part of a basket<br>data Basket = Basket { name:: String, item::Item }<br><br>-- The cart can have both kind of Baskets at the start of the program, or during runtime.<br>data Cart = List Basket<br><br>You can imagine this be a  shopping cart with fixed set of items. Where the count of<br>some of the items in the basket can be changed during shopping but not the count of the<br>items once they are tagged as frozen.<br><br>Therefore, valid operation are:<br><br>1. I can create an Basket with either FreeToChange item or CannotChange item.<br>2. I can update the count for FreeToChange item in the Basket<br>3. But, once I create an instance of the Basket to contain the CannotChange item,<br>   we cannot update the count anymore or update the Basket.<br><br>One approach I have taken is to throw an error if this happens  by pattern matching on type.  But, this is <br>an runtime check.<br><br>addToBasket :: Basket -> Basket<br>addToBasket b = let<br>  i = item b<br>  i' = case i of<br>    FreeToChange f -> FreeToChange {freeToChangeCount = f + 1}<br>    CannotChange f -> error ("This operation is not allowed")<br>  in<br>    b {item=i'}<br><br><br>Here are my questions:<br><br>1. Is there  a way to design the above data structures in such a way I could use the type system.  <br>2. Since, these are runtime changes, is it even a good design pattern to push this responsibility to a type system?<br><br><br>Thanks<br>Guru<br><br><br></div><br></div></div><span class="">_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.<br></span></blockquote></div><br></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.<br></blockquote></div><br></div>