[Haskell-cafe] SML vs Haskell types

Bob Ippolito bob at redivi.com
Fri Mar 12 22:44:32 UTC 2021


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
>>>
>>> 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.
>>>
>>> LB
>>>
>>>
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> To (un)subscribe, modify options or view archives go to:
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>>> Only members subscribed via the mailman list are allowed to post.
>>
>> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210312/3558db13/attachment.html>


More information about the Haskell-Cafe mailing list