Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Recursion with a self-defined type (Galaxy Being) 2. Re: Recursion with a self-defined type (Matthew Low) 3. Re: Recursion with a self-defined type (Galaxy Being) ---------------------------------------------------------------------- Message: 1 Date: Fri, 12 Mar 2021 10:19:16 -0600 From: Galaxy Being <borg...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: [Haskell-beginners] Recursion with a self-defined type Message-ID: <CAFAhFSW6gZX9-5f5OqKscj_DNZiGbf7cZ1TXTJb=3=7k4c7...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" I'm trying to translate *The Little MLer *into Haskell. I've got this data Shishkebab = Skewer | Onion Shishkebab | Lamb Shishkebab | Tomato Shishkebab deriving Show Then I have this which works veggieKebab :: Shishkebab -> Bool veggieKebab Skewer = True veggieKebab (Onion (shk)) = veggieKebab shk veggieKebab (Tomato (shk)) = veggieKebab shk veggieKebab (Lamb (shk)) = False > veggieKebab (Tomato (Onion (Tomato (Onion Skewer)))) True but I'm wondering if I could do something like this veggieKebab :: Shishkebab -> Bool veggieKebab Skewer = True veggieKebab (shkb (sk)) | (shkb == Onion) || (shkb == Tomato) = veggieKebab sk | otherwise = False This doesn't work, giving a "Parse error in pattern: shkb". I've been advised that I'm trying to treat what is a data constructor like a variable, but I can't fathom what that means in this case. What I'm trying to leverage is what I've learned from dealing with lists and recursion through the consed list. So if effect I'm trying to recurse through a consed Shishkebab object. It works in the first case, but hyow could I do this in this more generic way like the second try does? LB -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20210312/418bdcae/attachment-0001.html> ------------------------------ Message: 2 Date: Fri, 12 Mar 2021 17:27:21 -0700 From: Matthew Low <m...@ualberta.ca> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Recursion with a self-defined type Message-ID: <CAC=gTKyqccWzunj_XS8Ro-bZQwbM0TxS=3dgyavikfdtvcf...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Pattern matches in Haskell are based on matching specific data constructors, with underscores `_` as a "match anything" mechanism. So one way to achieve something like what you want is veggieKebab :: Shishkebab -> Bool veggieKebab Skewer = True veggieKebab (Onion (shk)) = veggieKebab shk veggieKebab (Tomato (shk)) = veggieKebab shk veggieKebab _ = False This works because the matches are considered in top-to-bottom order, so the last case only matches if all the others fail to. I'm not sure if it helps to build insight or not, but if you look at the the types of your data constructors in GHCI, you get, for example: λ> :t Onion Onion :: Shishkebab -> Shishkebab So even if you could pattern match as you wanted (veggieKebab (shkb (sk)) | (shkb == Onion)), you'd still be stuck with the problem of trying to compare two functions for equality, which isn't easy (and not something Haskell lets you do for arbitrary functions). You could get close to what you originally wrote by using a few more helper functions: startsWithOnion :: Shishkebab -> Bool startsWithOnion (Onion _) = True startsWithOnion _ = False startsWithTomato :: Shishkebab -> Bool startsWithTomato (Tomato _) = True startsWithTomato _ = False restOfKebab :: Shishkebab -> Shishkebab restOfKebab Skewer = Skewer restOfKebab (Onion rst) = rst restOfKebab (Tomato rst) = rst restOfKebab (Lamb rst) = rst veggieKebab :: Shishkebab -> Bool veggieKebab Skewer = True veggieKebab kebab | startsWithOnion kebab || startsWithTomato kebab = veggieKebab (restOfKebab kebab) | otherwise = False On Fri, Mar 12, 2021 at 9:19 AM Galaxy Being <borg...@gmail.com> wrote: > I'm trying to translate *The Little MLer *into Haskell. I've got this > > data Shishkebab = Skewer | Onion Shishkebab | Lamb Shishkebab | Tomato > Shishkebab deriving Show > > Then I have this which works > > veggieKebab :: Shishkebab -> Bool > veggieKebab Skewer = True > veggieKebab (Onion (shk)) = veggieKebab shk > veggieKebab (Tomato (shk)) = veggieKebab shk > veggieKebab (Lamb (shk)) = False > > > veggieKebab (Tomato (Onion (Tomato (Onion Skewer)))) > True > > but I'm wondering if I could do something like this > > veggieKebab :: Shishkebab -> Bool > veggieKebab Skewer = True > veggieKebab (shkb (sk)) | (shkb == Onion) || (shkb == Tomato) = > veggieKebab sk > | otherwise = False > > > This doesn't work, giving a "Parse error in pattern: shkb". I've been > advised that I'm trying to treat what is a data constructor like a > variable, but I can't fathom what that means in this case. What I'm trying > to leverage is what I've learned from dealing with lists and recursion > through the consed list. So if effect I'm trying to recurse through a > consed Shishkebab object. It works in the first case, but hyow could I do > this in this more generic way like the second try does? > > LB > > > > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20210312/313af267/attachment-0001.html> ------------------------------ Message: 3 Date: Fri, 12 Mar 2021 22:24:44 -0600 From: Galaxy Being <borg...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Recursion with a self-defined type Message-ID: <CAFAhFSV8M9OPq4CP8hZNZE_tQEKoTBB7Qj+uxSy2pEe32a=u...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" So because Onion Shishkebab in the type definition is technically a data constructor *function, *the (shkb == Onion) in the code is comparing function-to-function, i.e., won't work. Thanks. The light finally went on. On Fri, Mar 12, 2021 at 6:28 PM Matthew Low <m...@ualberta.ca> wrote: > Pattern matches in Haskell are based on matching specific data > constructors, with underscores `_` as a "match anything" mechanism. So one > way to achieve something like what you want is > > veggieKebab :: Shishkebab -> Bool > veggieKebab Skewer = True > veggieKebab (Onion (shk)) = veggieKebab shk > veggieKebab (Tomato (shk)) = veggieKebab shk > veggieKebab _ = False > > This works because the matches are considered in top-to-bottom order, so > the last case only matches if all the others fail to. > > I'm not sure if it helps to build insight or not, but if you look at the > the types of your data constructors in GHCI, you get, for example: > > λ> :t Onion > Onion :: Shishkebab -> Shishkebab > > So even if you could pattern match as you wanted (veggieKebab (shkb (sk)) > | (shkb == Onion)), you'd still be stuck with the problem of trying to > compare two functions for equality, which isn't easy (and not something > Haskell lets you do for arbitrary functions). You could get close to what > you originally wrote by using a few more helper functions: > > startsWithOnion :: Shishkebab -> Bool > startsWithOnion (Onion _) = True > startsWithOnion _ = False > > startsWithTomato :: Shishkebab -> Bool > startsWithTomato (Tomato _) = True > startsWithTomato _ = False > > restOfKebab :: Shishkebab -> Shishkebab > restOfKebab Skewer = Skewer > restOfKebab (Onion rst) = rst > restOfKebab (Tomato rst) = rst > restOfKebab (Lamb rst) = rst > > veggieKebab :: Shishkebab -> Bool > veggieKebab Skewer = True > veggieKebab kebab | startsWithOnion kebab || startsWithTomato kebab = > veggieKebab (restOfKebab kebab) > | otherwise = False > > > > On Fri, Mar 12, 2021 at 9:19 AM Galaxy Being <borg...@gmail.com> wrote: > >> I'm trying to translate *The Little MLer *into Haskell. I've got this >> >> data Shishkebab = Skewer | Onion Shishkebab | Lamb Shishkebab | Tomato >> Shishkebab deriving Show >> >> Then I have this which works >> >> veggieKebab :: Shishkebab -> Bool >> veggieKebab Skewer = True >> veggieKebab (Onion (shk)) = veggieKebab shk >> veggieKebab (Tomato (shk)) = veggieKebab shk >> veggieKebab (Lamb (shk)) = False >> >> > veggieKebab (Tomato (Onion (Tomato (Onion Skewer)))) >> True >> >> but I'm wondering if I could do something like this >> >> veggieKebab :: Shishkebab -> Bool >> veggieKebab Skewer = True >> veggieKebab (shkb (sk)) | (shkb == Onion) || (shkb == Tomato) = >> veggieKebab sk >> | otherwise = False >> >> >> This doesn't work, giving a "Parse error in pattern: shkb". I've been >> advised that I'm trying to treat what is a data constructor like a >> variable, but I can't fathom what that means in this case. What I'm trying >> to leverage is what I've learned from dealing with lists and recursion >> through the consed list. So if effect I'm trying to recurse through a >> consed Shishkebab object. It works in the first case, but hyow could I do >> this in this more generic way like the second try does? >> >> LB >> >> >> >> >> >> _______________________________________________ >> Beginners mailing list >> Beginners@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20210312/374bd7f6/attachment.html> ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 152, Issue 4 *****************************************