user28522
user28522

Reputation: 321

Implementing Cont Applicative instance

I got the following error when implementing the Applicative instance for Cont.

Couldn't match expected type ‘r’ with actual type ‘Cont r b’ ‘r’ is a rigid type variable bound by ...

newtype Cont r a = Cont {(>>-) :: (a -> r) -> r}

instance Functor (Cont r) where
  -- fmap :: (a -> b) -> (Cont r) a -> (Cont r) b
  fmap f (Cont cps_a) = Cont $ \cps -> cps_a (cps . f)

instance Applicative (Cont r) where
  -- pure :: a -> Cont r a
  pure x = Cont ($ x)
  -- (<*>) Cont r (a -> b) -> Cont r a -> Cont r b
  (Cont cps_f) <*> cont_cps_a = cps_f (\f -> fmap f cont_cps_a)

I am trying to use fmap in defining (<*>), extracting f from the left cps value then fmap f over the right cps value. I am not sure where I made the mistake.

Upvotes: 2

Views: 258

Answers (1)

assembly.jc
assembly.jc

Reputation: 2066

It is obvious that the type of expression cps_f (\f -> fmap f cont_cps_a) is invalid . Since

fmap f cont_cps_a :: Cont r b

and

\f -> fmap f cont_cps_a :: (a->b)->Cont r b

and

cps_f :: ((a->b)->r)->r

cps_f need parameter type as (a->b)->r, but now is (a->b)->Cont r b.

Instead of using fmap, you still can implements <*> operator similar to the way as your fmap function as

(Cont cps_f) <*> Cont cps_a = Cont $ \cps_b -> cps_f (\f -> cps_a (cps_b . f))

Upvotes: 5

Related Questions