简体   繁体   中英

Making instance of Applicative

Still not a hundred percent shure how to make instances of the more complex types. Have this:

data CouldBe a = Is a | Lost deriving (Show, Ord) 

Made an instance of Functor , using Maybe as an example:

instance Functor CouldBe where 
  fmap f (Is x) = Is (f x) 
  fmap f Lost   = Lost 

For doing something like this:

tupleCouldBe :: CouldBe a -> CouldBe b -> CouldBe (a,b)
tupleCouldBe x y = (,) <$> x <*> y

CouldBe needs to be an instance of Applicative , but how would you go about that? Sure I can look it up and copy it, but I want to learn the process behind it and finally end up with the instance declaration of CouldBe.

You just write it out, following the types:

instance Applicative CouldBe where
   {- 
        
          pure, ((<*>) | liftA2)

      pure :: a -> f a 
      pure :: a -> CouldBe a

      liftA2 :: (a -> b -> c) -> f a -> f b -> f c 
      liftA2 :: (a -> b -> c) -> CouldBe a -> CouldBe b -> CouldBe c 
   -}
    pure a = fa
        where
        fa = ....

    liftA2 abc fa fb = fc
        where
        fc = ....

According to

data CouldBe a = Is a | Lost

our toolset is

Is   :: a -> CouldBe a
Lost :: CouldBe a

but we can also use pattern matching, eg

couldBe   is   lost  (Is a)    = is a
couldBe   is   lost  (Lost)    = lost
couldBe :: ? -> ? -> CouldBe a -> b
couldBe :: ? -> b -> CouldBe a -> b
couldBe :: (a -> b) -> b -> CouldBe a -> b

So,

    -- pure :: a -> f a 
    pure :: a -> CouldBe a     

matches up with

    Is   :: a -> CouldBe a

so we define

    pure a = Is a

Then, for liftA2 , we follow the data cases:

    -- liftA2 :: (a -> b -> c) -> f a -> f b -> f c 
    -- liftA2 :: (a -> b -> c) -> CouldBe a -> CouldBe b -> CouldBe c
    liftA2 abc Lost    _     = ...
    liftA2 abc  _     Lost   = ...
    liftA2 abc (Is a) (Is b) = fc
        where
        c = abc a b
        fc = ....     -- create an `f c` from `c`: 
                      -- do we have a `c -> CouldBe c` ?
                      -- do we have an `a -> CouldBe a` ? (it's the same type)

But in the first two cases we don't have an a or a b ; so we have to come up with a CouldBe c out of nothing. We do have this tool in our toolset as well.

Having completed all the missing pieces, we can substitute the expressions directly into the definitions, eliminating all the unneeded interim values / variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM