Home > Mobile >  How to create the instance for my own type?
How to create the instance for my own type?

Time:11-17

I'm new to Haskell, learning Functor, Applicative, and Monad.

I checked the Functor instance for Either type from hackage is:

 data  Either a b  =  Left a | Right b

 instance Functor (Either a) where
    fmap _ (Left x) = Left x
    fmap f (Right y) = Right (f y)

and I am asked to do the Functor, Applicative, Monad instance for extended Either called MyEither:

data MyEither a b = MyLeft a | MyRight b | Nothing
    deriving (Eq, Show)

My question is:

1 How to extend Nothing in my instance?

2 Does deriving have to be written in the instance?

Can anyone get me some tips?

CodePudding user response:

When you implement the instance you don't need to write deriving. deriving is for when you let the compiler derive an instance for you when you are defining a new type.

For Nothing, pattern match on it and return Nothing for the implementation of all of FAM. There isn't much you can do with it.

Here is a similar example that may help you.

data Nope a = NopeDataJpg deriving (Eq, Show)

instance Functor Nope where
  fmap _ _ = NopeDataJpg
  
instance Applicative Nope where
  pure x = NopeDataJpg
  _ <*> _ = NopeDataJpg

instance Monad Nope where
  return = pure
  _ >>= _ = NopeDataJpg

Also, here are the Functor, Applicative, and Monad implementations of Maybe in GHC. How they handle Nothing is pretty similar to what you need to do for your data type.

CodePudding user response:

When you write down your instances, start by writing out the types explicitly:

data MyEither a b = MyLeft a | MyRight b | MyNothing
    deriving (Eq, Show)

instance Functor (MyEither a) where
    -- fmap :: Functor  f => (b -> c) -> f b -> f c
    -- fmap :: (b -> c) -> MyEither a b -> MyEither a c

(I'll use MyNothing here to prevent any mix-ups with the Maybe's Nothing).

And now we are ready to enumerate all possibilities according to the data type definition:

    fmap bc (MyLeft aValue) = result   where
    --   bc                ::            b -> c
    --       MyLeft aValue :: MyEither a b
    --   result            :: MyEither a      c
    .....

here we must produce a value of type MyEither a c as the result. The function bc is useless here, as we only have access to the value aValue :: a of type a:

             MyLeft aValue :: MyEither a b
           --------------------------------
                    aValue ::          a

Thus we have two possibilities here:

  1. result = MyLeft aValue which will construct a new value, this time of type MyEither a c as determined by the type signature; or
  2. result = ....

Fill the dots, and make the choice between 1. and 2, completing the definition of this clause, fmap bc (MyLeft aValue) = ....

The next possibility is

    fmap bc (MyRight bValue) = ...

This time we do have an access to a value of type b, so the function bc can come quite handy, since

          bValue :: b
       bc        :: b -> c
     -------------------------
       bc bValue ::      c

and

                cValue ::            c
       --------------------------------
        myRight cValue :: MyEither a c

Thus the natural definition for that clause is

    fmap bc (MyRight bValue) = MyRight cValue
             where
             cValue =  .... 

although of course the same second option is also technically possible as was in the first clause. What's certainly impossible is to use MyLeft to construct a MyEither a c value here, as we have absolutely no access to any a type value at all here.... except undefined.

And now there's only one more possibility left, for a value of type MyEither a b that our fmap must handle, according to it type signature (remember, fmap :: (b -> c) -> MyEither a b -> MyEither a c). An that value is ...

    fmap bc MyNothing = 

Again, we must produce a value of type MyEither a c as the result. This time we have no access to any value of type neither b nor a. So there is no other choice other than return ...

                       .......

(sans the uses of undefined of course). Do complete the definition.

And I hope you are now able to finish up the other definitions as needed.

  • Related