ceno980
ceno980

Reputation: 2011

Understanding the <$> operator

I have the following type:

newtype Rep f a = Rep { runRep :: String -> f (String, a) }

The type Rep f a is a stateful computation that takes a String as the initial state and produces a (String, a) as the result of the computation. The result of the computation is wrapped in the functor f.

The applicative instance for Rep is the following:

instance Monad f => Applicative (Rep f) where 
    pure x = Rep $ \s -> pure (s, x)
    Rep f <*> Rep x = Rep $ \s -> do 
        (s',rf)  <- f s 
        (s'',rx) <- x s'
        return (s'', rf rx)

And the monad instance for Rep is the following:

instance Monad f => Monad (Rep f) where 
   return x = pure x 
   Rep a >>= f = Rep $ \s -> do
    (s', ya) <- a s
    let (Rep f') = f ya
    (s'', yf) <- f' s'
    pure (s'', yf)

I have the following data types and function:

data TD = Empty | Fol TD TD | Letters [Char]

data Res = Nil | Character Char | Cop Res Res | Special [Res]

findmatch (Fol a b) = do
   ra <- findmatch a
   rb <- findmatch b
   pure (Cop ra rb)

findmatch (Fol a b) = Cop <$> findmatch a <*> findmatch b

I am having trouble understanding how the second definition of findmatch involving the <$> works. I know that <$> has the following type declaration:

(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x

The first argument to <$> should be a function, whilst the second should be a value wrapped in a functor. The result of findmatch is a value wrapped in a functor, however is Cop a function in this case? I know that Cop is a value constructor that takes two arguments of type Res. If one argument of type Res is passed to Cop, which is what I think occurs in Cop <$> findmatch a, this would return another function which takes a value of type Res. However, I am not sure what would be the type of the result that is returned by this second function that resulted from the partial application.

Any insights are appreciated.

Upvotes: 1

Views: 101

Answers (1)

Bergi
Bergi

Reputation: 664185

However is Cop a function in this case? I know that Cop is a value constructor that takes two arguments of type Res.

Yes, Cop is a function with two parameters. It has the type Cop :: Res -> Res -> Res.

If one argument of type Res is passed to Cop, this would return another function which takes a value of type Res.

Yes. Cop <$> findmatch a :: Functor f => f (Res -> Res)

What would the type of the result that is returned by this second function that resulted from the partial application.

It's the type of the value that is constructed by the Cop constructor: it's constructing Res values.

Upvotes: 2

Related Questions