<div dir="ltr">So embarrassing. Thanks. Anyway, this is what works<div><br></div><div><font face="monospace">data Shish2 a = Holder2 a | Onion2 (Shish2 a) | Lamb2 (Shish2 a) | Tomato2 (Shish2 a)<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">whatHolder2 (Holder2 (sh)) = sh<br>whatHolder2 (Onion2 (sk)) = whatHolder2 sk<br>whatHolder2 (Tomato2 (sk)) = whatHolder2 sk<br>whatHolder2 (Lamb2 (sk)) = whatHolder2 sk<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">meal6 = (Onion2 (Tomato2 (Lamb2 (Holder2 (Fork)))))<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">> whatHolder2 meal6<br></font></div><div><font face="monospace">Fork</font></div><div><br></div><div>However, I'm still wondering how to have an abstracted (x:xs) - like pattern to collapse all the ingredients, i.e.,</div><div><br></div><div>whatHolder2 (Holder2 (sh)) = sh<br>whatHolder2 (shish2-head (shish2-tail)) = whatHolder2 shish2-tail<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 12, 2021 at 4:44 PM Bob Ippolito <<a href="mailto:bob@redivi.com">bob@redivi.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I think the problem is that you have a typo such that this Shish2 is dependent on some other data type named Shish. If you change the type name to Shish (or change its definition to use Shish2) it works fine.<div><br></div><div>data Shish a = Holder2 a | Onion (Shish a) | Lamb (Shish a) | Tomato (Shish a) deriving Show<br>data Rod = Dagger | Fork | Sword deriving Show<br><br>meal6 = (Onion (Tomato (Lamb (Holder2 (Fork)))))</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 12, 2021 at 2:23 PM Galaxy Being <<a href="mailto:borgauf@gmail.com" target="_blank">borgauf@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">So are you saying<div><br></div><div><font face="monospace">data Shish2 a = Holder2 a | Onion (Shish a) | Lamb (Shish a) | Tomato (Shish a)</font><br></div><div><br></div><div>but then I'm having trouble with </div><div><br></div><div><font face="monospace">meal6 = (Onion (Tomato (Lamb (Holder2 (Fork)))))<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">Couldn't match expected type `Shish a1'<br>                  with actual type `Shish2 a0'<br>    * In the first argument of `Tomato', namely<br>        `(Lamb (Holder2 (Fork)))'<br>      In the first argument of `Onion', namely<br>        `(Tomato (Lamb (Holder2 (Fork))))'<br>      In the expression: (Onion (Tomato (Lamb (Holder2 (Fork)))<br></font></div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 12, 2021 at 4:08 PM Tikhon Jelvis <<a href="mailto:tikhon@jelv.is" target="_blank">tikhon@jelv.is</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">Onion of 'a shish is equivalent to Onion (Shish a) in Haskell rather than Onion a (Shish a).<div dir="auto"><br></div><div dir="auto">The latter version in Haskell creates a constructor with two arguments, something like Onion of ('a * 'a shish) would in SML. (Or, at least, OCaml—not 100% familiar with SML syntax myself!)</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 12, 2021, 14:03 Galaxy Being <<a href="mailto:borgauf@gmail.com" target="_blank">borgauf@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello,<div><br></div><div>This is my first post here, and it's an odd one, I'll admit. Basically, I'm trying to translate the material in <i>The Little MLer </i>to Haskell, the TLMLer being an excellent types workout. So in SML I have this</div><div><br></div><div><font face="monospace">datatype 'a shish = Bottom of 'a | Onion of 'a shish | Lamb of 'a shish | Tomato of 'a shish</font><br></div><div><br></div><div>and this</div><div><br></div><div><font face="monospace">datatype rod =  Dagger | Fork | Sword</font><br></div><div><br></div><div>and then this SML function</div><div><br></div><div><font face="monospace">fun is_veggie (Bottom (x)) = true<br>  | is_veggie (Onion (x)) = is_veggie (x)<br>  | is_veggie (Lamb (x)) = false<br>  | is_veggie (Tomato (x)) = is_veggie (x)</font><br></div><div><br></div><div>which has no problem handling tis</div><div><br></div><div><font face="monospace">is_veggie (Onion(Tomato(Bottom(Dagger))))</font><br></div><div><br></div><div>Now, in Haskell I've translated this (with minor alterations) to</div><div><br></div><div><font face="monospace">data Shish a = Holder a | Onion a (Shish a) | Lamb a (Shish a) | Tomato a (Shish a)<br></font></div><div><font face="monospace">data Rod = Dagger | Fork | Sword</font><br></div><div><br></div><div>However, in Haskell these two expressions are different things entirely</div><div><br></div><div><font face="monospace">meal4 = Tomato Dagger (Onion Fork (Lamb Spear (Holder Fork)))<br></font></div><div><font face="monospace">meal5 = (Tomato (Onion (Lamb (Holder Fork))))</font><br></div><div><br></div><div>Here's my attempt at handling <font face="monospace">meal4</font> with a Haskell <font face="monospace">isVeggie</font></div><div><br></div><div><font face="monospace">isVeggie (Holder (sh)) = True<br>isVeggie (Onion sh (sk)) = isVeggie sk<br>isVeggie (Tomato sh (sk)) = isVeggie sk<br>isVeggie (Lamb sh (sk)) = False<br></font></div><div><br></div><div>This works for <font face="monospace">meal4</font>, but not for <font face="monospace">meal5</font>. And yet in the SML world their <font face="monospace">is_veggie</font> handles <font face="monospace">(Onion(Tomato(Bottom(Dagger))))</font> just fine. TLMLer says </div><div><br></div><div><font face="monospace">Onion (Tomato (Bottom (Dagger)))</font></div><div><br></div><div>belongs to the type <font face="monospace">rod shish</font>, while in Haskell</div><div><br></div><div>Onion (Tomato (Holder (Dagger)))</div><div><br></div><div>is a bizarre nested beast due to the fact that the data constructor variable of <font face="monospace">Onion </font>is <font face="monospace">Tomato (Holder (Dagger))</font> etc. etc.</div><div><br></div><div>Can a single Haskell version of <font face="monospace">isVeggie</font> handle both <font face="monospace">meal4</font> and <font face="monospace">meal5</font>? No? I thought so. But then how would a separate Haskell version of <font face="monospace">isVeggie</font> handle <font face="monospace">meal5</font> -- or is it just too weird? Also, but not critical, how could the Haskell isVeggie be done with guards, i.e., just like a consed list is matched on (x:xs) in the recursion case? I can see that <font face="monospace">1:2:3:[</font>] and <font face="monospace">Onion (Tomato (Bottom (Dagger))) </font><font face="arial, sans-serif">are both conses, but the latter I don't know how to break out into head and tail for a guard case where the individual food items were not mentioned explicitly. IOW, this doesn't work</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="monospace">isVeggieKebab :: Shish -> Bool<br>isVeggieKebab Holder (sk) = True<br>isVeggieKebab (shkb (sk)) | (shkb == Onion) || (shkb == Tomato) = isVeggieKebab sk<br>                        | otherwise = False</font><font face="arial, sans-serif"><br></font></div><div><br></div><div>I'm feeling some doom and gloom about this project. Right at the start this seems to be an insurmountable difference between SML and Haskell type systems. Or I simply don't understand something fundamental here.</div><div><br></div><div>LB</div><div><br></div><div><br></div></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 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>
</blockquote></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>
</blockquote></div>