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. Re: Functor instance (Steven Leiva) 2. Re: Functor instance (Sylvain Henry) ---------------------------------------------------------------------- Message: 1 Date: Mon, 5 Mar 2018 09:38:22 -0600 From: Steven Leiva <leiva.ste...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Functor instance Message-ID: <CA+=wos4g2s4jxwvpfbvrpj1k_2t83rafxucelgwjkgghmkr...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Hilco, I am going to use a lot of Haskell concepts here, but I am a strong believer that using the correct terms empowers the learner to go out and continue their education on their own. *Your first question is is it possible to define Result as Result success failure and still create an instance of Functor?* The answer to that is *yes*. We can look up the definition of the *Functor typeclass* (use *:i Functor* in GHCI), and we can see the following: *class Functor (f :: * -> *) where*.... >From that definition, we can see that we can have an instance of Functor for any type that has the *kind * -> **. It seems like you are familiar with treating type constructors as functions at the type level, so what we are saying here is that in order for a type constructor to be a functor, it *has* to be a type constructor that takes *one* type constant to yield another type constant. Your type *Result* has the kind ** -> * -> **. It takes two type constants, so we know that wont "fit" into Functor, and we have to partially apply the *Result* type constructor to get another type constructor with the kind ** -> **, which can have an instance of Functor. What I think is missing from your understanding is this - if you change your data declaration to be *Result success failure*, then your instance of functor will only be able to modify the failure case. Why? Because when you write your instance of functor, it will look like this: *instance Functor (Result success) where...*. If we look at the signature of *fmap :: (a -> b) -> f a -> f b*, and then we specialize so that *f ~ Result success*, we get *fmap :: (a -> b) -> Result success a -> Result success b*. In other words, you have already baked in the first type argument to *Result* when you are writing your instance of Functor for it, and are not allowed to change it anymore. *Your second question I would like to be able to express that "result" is not touched...* I am assuming here that you are talking about this piece of code "fmap _ result@(Failure error) = result" using your original functor instance and data Result failure success... We can't express that result is not touched. Why? Because result *is* touched. It has to be. As you yourself mentioned, on the left-hand side we have a value of one type, and on the right-hand side we have a value of a different type. Even though we don't witness the change at the value level, we do have a change at the type level. So we can't express it because it is not what is happening. Now, I get what you are saying - the result on the left-hand side has the same data as the right-hand side, same data constructor, etc, but it is still not the same value. On your third question, regarding GHC being smart enough to realize a NOP, I don't know. I hope this helps! On Sat, Mar 3, 2018 at 2:32 PM, Hilco Wijbenga <hilco.wijbe...@gmail.com> wrote: > Hi all, > > I'm trying to implement my own Result type (and yes, I'm aware you can > abuse Either for this :-) ) but doing something as (seemingly?) simple > as implementing a Functor instance was surprisingly difficult. > > data Result failure success > = Success success > | Failure failure > > instance Functor (Result failure) where > fmap f (Success value) = Success (f value) > fmap _ (Failure error) = Failure error > -- fmap _ result@(Failure error) = result > -- fmap _ result = result > > 1) Is it possible to define "Result" as "Result success failure" > (instead of "Result failure success") and _still_ create an instance > of Functor? > 2) The two alternatives for fmap for the Failure scenario do not > compile (the end result is "Result failure a" instead of "Result > failure b") and that makes sense. But I would like to be able to > express that "result" is not touched. Is there any way to do that? > 3) And while wondering about that, is GHC smart enough to realize that > "= Failure error" in the failure scenario is actually a NOP? (I'm just > curious.) > > Cheers, > Hilco > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- Steven Leiva 305.528.6038 leiva.ste...@gmail.com http://www.linkedin.com/in/stevenleiva -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20180305/b92380c8/attachment-0001.html> ------------------------------ Message: 2 Date: Mon, 5 Mar 2018 22:21:45 +0100 From: Sylvain Henry <sylv...@haskus.fr> To: beginners@haskell.org Subject: Re: [Haskell-beginners] Functor instance Message-ID: <b45cd223-fce3-3404-6cd5-b84ce6632...@haskus.fr> Content-Type: text/plain; charset=utf-8; format=flowed > 3) And while wondering about that, is GHC smart enough to realize that > "= Failure error" in the failure scenario is actually a NOP? (I'm just > curious.) Yes it does. The STG CSE pass handles this. Sylvain ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 117, Issue 5 *****************************************