Galaxy Being borgauf at gmail.com
Sat Mar 13 00:59:52 UTC 2021

```So embarrassing. Thanks. Anyway, this is what works

data Shish2 a = Holder2 a | Onion2 (Shish2 a) | Lamb2 (Shish2 a) | Tomato2
(Shish2 a)

whatHolder2 (Holder2 (sh)) = sh
whatHolder2 (Onion2 (sk)) = whatHolder2 sk
whatHolder2 (Tomato2 (sk)) = whatHolder2 sk
whatHolder2 (Lamb2 (sk)) = whatHolder2 sk

meal6 = (Onion2 (Tomato2 (Lamb2 (Holder2 (Fork)))))

> whatHolder2 meal6
Fork

However, I'm still wondering how to have an abstracted (x:xs) - like
pattern to collapse all the ingredients, i.e.,

whatHolder2 (Holder2 (sh)) = sh
whatHolder2 (shish2-head (shish2-tail)) = whatHolder2 shish2-tail

On Fri, Mar 12, 2021 at 4:44 PM Bob Ippolito <bob at redivi.com> wrote:

> 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.
>
> data Shish a = Holder2 a | Onion (Shish a) | Lamb (Shish a) | Tomato
> (Shish a) deriving Show
> data Rod = Dagger | Fork | Sword deriving Show
>
> meal6 = (Onion (Tomato (Lamb (Holder2 (Fork)))))
>
>
> On Fri, Mar 12, 2021 at 2:23 PM Galaxy Being <borgauf at gmail.com> wrote:
>
>> So are you saying
>>
>> data Shish2 a = Holder2 a | Onion (Shish a) | Lamb (Shish a) | Tomato
>> (Shish a)
>>
>> but then I'm having trouble with
>>
>> meal6 = (Onion (Tomato (Lamb (Holder2 (Fork)))))
>>
>> Couldn't match expected type `Shish a1'
>>                   with actual type `Shish2 a0'
>>     * In the first argument of `Tomato', namely
>>         `(Lamb (Holder2 (Fork)))'
>>       In the first argument of `Onion', namely
>>         `(Tomato (Lamb (Holder2 (Fork))))'
>>       In the expression: (Onion (Tomato (Lamb (Holder2 (Fork)))
>>
>>
>>
>>
>> On Fri, Mar 12, 2021 at 4:08 PM Tikhon Jelvis <tikhon at jelv.is> wrote:
>>
>>> Onion of 'a shish is equivalent to Onion (Shish a) in Haskell rather
>>> than Onion a (Shish a).
>>>
>>> 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!)
>>>
>>> On Fri, Mar 12, 2021, 14:03 Galaxy Being <borgauf at gmail.com> wrote:
>>>
>>>> Hello,
>>>>
>>>> This is my first post here, and it's an odd one, I'll admit. Basically,
>>>> I'm trying to translate the material in *The Little MLer *to Haskell,
>>>> the TLMLer being an excellent types workout. So in SML I have this
>>>>
>>>> datatype 'a shish = Bottom of 'a | Onion of 'a shish | Lamb of 'a
>>>> shish | Tomato of 'a shish
>>>>
>>>> and this
>>>>
>>>> datatype rod =  Dagger | Fork | Sword
>>>>
>>>> and then this SML function
>>>>
>>>> fun is_veggie (Bottom (x)) = true
>>>>   | is_veggie (Onion (x)) = is_veggie (x)
>>>>   | is_veggie (Lamb (x)) = false
>>>>   | is_veggie (Tomato (x)) = is_veggie (x)
>>>>
>>>> which has no problem handling tis
>>>>
>>>> is_veggie (Onion(Tomato(Bottom(Dagger))))
>>>>
>>>> Now, in Haskell I've translated this (with minor alterations) to
>>>>
>>>> data Shish a = Holder a | Onion a (Shish a) | Lamb a (Shish a) | Tomato
>>>> a (Shish a)
>>>> data Rod = Dagger | Fork | Sword
>>>>
>>>> However, in Haskell these two expressions are different things entirely
>>>>
>>>> meal4 = Tomato Dagger (Onion Fork (Lamb Spear (Holder Fork)))
>>>> meal5 = (Tomato (Onion (Lamb (Holder Fork))))
>>>>
>>>> Here's my attempt at handling meal4 with a Haskell isVeggie
>>>>
>>>> isVeggie (Holder (sh)) = True
>>>> isVeggie (Onion sh (sk)) = isVeggie sk
>>>> isVeggie (Tomato sh (sk)) = isVeggie sk
>>>> isVeggie (Lamb sh (sk)) = False
>>>>
>>>> This works for meal4, but not for meal5. And yet in the SML world
>>>> their is_veggie handles (Onion(Tomato(Bottom(Dagger)))) just fine.
>>>> TLMLer says
>>>>
>>>> Onion (Tomato (Bottom (Dagger)))
>>>>
>>>> belongs to the type rod shish, while in Haskell
>>>>
>>>> Onion (Tomato (Holder (Dagger)))
>>>>
>>>> is a bizarre nested beast due to the fact that the data constructor
>>>> variable of Onion is Tomato (Holder (Dagger)) etc. etc.
>>>>
>>>> Can a single Haskell version of isVeggie handle both meal4 and meal5?
>>>> No? I thought so. But then how would a separate Haskell version of
>>>> isVeggie handle meal5 -- 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 1:2:3:[] and Onion (Tomato (Bottom (Dagger))) 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
>>>>
>>>> isVeggieKebab :: Shish -> Bool
>>>> isVeggieKebab Holder (sk) = True
>>>> isVeggieKebab (shkb (sk)) | (shkb == Onion) || (shkb == Tomato) =
>>>> isVeggieKebab sk
>>>>                         | otherwise = False
>>>>
>>>> this seems to be an insurmountable difference between SML and Haskell type
>>>> systems. Or I simply don't understand something fundamental here.
>>>>
>>>> LB
>>>>
>>>>
>>>> _______________________________________________
>>>> To (un)subscribe, modify options or view archives go to:
>>>> Only members subscribed via the mailman list are allowed to post.
>>>
>>> _______________________________________________