<div dir="ltr">Please excuse me an off-topic question, <b>MarLinn</b> can you say what apostrophe means in `<span style="color:rgb(33,33,33);line-height:1.5"><font face="monospace">Item 'Changeable</font></span><span style="line-height:1.5">`?</span><br></div><br><div class="gmail_quote"><div dir="ltr">ср, 3 авг. 2016 г. в 20:00, MarLinn via Haskell-Cafe <<a href="mailto:haskell-cafe@haskell.org">haskell-cafe@haskell.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<p>I'll try to address the questions in the reverse order.</p></div><div bgcolor="#FFFFFF" text="#000000">
<p><br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>
<div>
<div>Does this approach give me any more power than the
previous approaches? The one power is that we stop
the user from being able to construct the Frozen type,
and we leave it to the compiler to return that type
based on the inference. Correct? Is there any other
power.</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div><div bgcolor="#FFFFFF" text="#000000"><p>The main power lies in the minimalism. You don't need special
handling of an <i>Either</i> or manual tracking because the types
do everything you need.</p></div><div bgcolor="#FFFFFF" text="#000000">
<p><br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>
<div>
<div>In your approach or in the approach suggested by
others, ultimately, I end up handling the 'Frozen'
type during run-time.</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div><div bgcolor="#FFFFFF" text="#000000"><p>Actually, not really. That's the beauty of phantom types: It's
almost exclusively a development-time tool that vanishes once the
program is compiled. You can't handle the Frozen type during
run-time because it will have been dropped - unless you use tricks
to keep it, of course. It might feel like you're dealing with the
type, but it's all in your head.</p></div><div bgcolor="#FFFFFF" text="#000000">
<p><br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>
<div>
<div>There is no way from stopping somene write code
that calls update's on Frozen. (For example while
mapping..). Is that understanding correct?<br>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div><div bgcolor="#FFFFFF" text="#000000"><p>Here's my <i>Item</i> type again for reference:</p></div><div bgcolor="#FFFFFF" text="#000000">
<pre> data Item (c :: Changeability) = Item { plainItem :: PlainItem }</pre></div><div bgcolor="#FFFFFF" text="#000000">
If you don't export the <i>Item</i> constructor, you have full
control over who gets to do what with your items. If your only
exported update function is</div><div bgcolor="#FFFFFF" text="#000000"><br>
<pre> changeItem :: (PlainItem -> PlainItem) -> Item 'Changeable -> Item 'Changeable</pre>
</div><div bgcolor="#FFFFFF" text="#000000"><p>then only non-frozen items can be changed, as the type signature
says. Of course you have to be careful, e.g. you wouldn't want to
export a function like</p>
<pre> asChangableItem :: PlainItem -> Item 'Changeable</pre>
<p>
because then somebody could "unfreeze" items. But as long as you
watch your types and exports, you should be fine. (apart from
unsafe casting and the like, naturally)</p></div><div bgcolor="#FFFFFF" text="#000000">
<br>
<blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>
<div>1. With the definition of Basket c, how do I create
a type such as <br>
<br>
</div>
Cart = [Basket]. The only way to create such a cart is
Cart c = [Basket c]. But, that ties the Cart to one
definition of Basket. Is there a way around this? I might
be missing something simple.<br>
</div>
</div>
</div>
</div>
</blockquote>
</div><div bgcolor="#FFFFFF" text="#000000"><p>That depends. How does a cart behave, depending on the
changeability of its contents?</p>
<ul>
<li>
<p><i>If a cart with any frozen value behaves differently from a
cart with only changeable baskets</i> then add a phantom
type to the cart as well. Control the channels into it and
have the cart type change depending on what you insert.</p>
</li>
<li>
<p><i>If all carts behave the same and contents don't matter</i>
just store <i>PlainBasket</i>s, i.e. a <i>Basket</i> without
the annotation.</p>
</li>
<li>
<p><i>If you want to be able to map over baskets in a cart while
handling frozen ones</i><i> differently</i>, then you need
both run-time information about basket changeability and a way
to share functions between the two different types. The
canonical way to share a function between types is a class:<br>
</p>
<pre> class IsBasket b
instance IsBasket (Basket c)
type Cart = (IsBasket b) => [b] -- not a good definition, but you get the point
</pre>
<p>Now <i>Basket</i>s can share functions but behave
differently. Of course once you need such a class anyway you
could ask why you would not want to use it exclusively instead
of the phantom types. It's a matter of taste, I guess.<br>
</p>
</li>
</ul>
</div>
_______________________________________________<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.</blockquote></div>