Send Beginners mailing list submissions to

To subscribe or unsubscribe via the World Wide Web, visit
or, via email, send a message with subject or body 'help' to

You can reach the person managing the list at

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 <>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <>
Subject: Re: [Haskell-beginners] Functor instance
Content-Type: text/plain; charset="utf-8"


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

> 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

Steven Leiva
-------------- next part --------------
An HTML attachment was scrubbed...


Message: 2
Date: Mon, 5 Mar 2018 22:21:45 +0100
From: Sylvain Henry <>
Subject: Re: [Haskell-beginners] Functor instance
Message-ID: <>
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.



Subject: Digest Footer

Beginners mailing list


End of Beginners Digest, Vol 117, Issue 5

Reply via email to