<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>