Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `apply` from `MyApplicative ((,) e)`

Tags:

haskell

Given the following, taken from Typeclassopedia:

class MyApplicative f where
    pure :: a          -> f a
    ap   :: f (a -> b) -> f a -> f b

instance Monoid e => MyApplicative ((,) e) where
  pure x             = (mempty, x)
  (u, f) `ap` (v, x) = (u `mappend` v, f x)

I'm trying to do something like:

ghci> (+) <$> Control.Applicative.pure 100 <*> Control.Applicative.pure 50
150

but, with the newly defined Applicative:

ghci> Main.pure (+ 100) `ap` (Main.pure 50)

<interactive>:132:1:
    No instance for (MyApplicative f0) arising from a use of `it'
    The type variable `f0' is ambiguous
    Note: there is a potential instance available:
      instance Monoid e => MyApplicative ((,) e)
        -- Defined at MonoidWork.hs:8:10
    In the first argument of `print', namely `it'
    In a stmt of an interactive GHCi command: print it

Looking at the types:

ghci> :t Main.pure (+ 100)
Main.pure (+ 100) :: (MyApplicative f, Num a) => f (a -> a)

and

ghci> :t (Main.pure 50)
(Main.pure 50) :: (MyApplicative f, Num a) => f a

I don't understand how to fix the compile-time error.

like image 857
Kevin Meredith Avatar asked May 04 '15 01:05

Kevin Meredith


1 Answers

You just need to give it a type signature. GHC/GHCi has special rules for defaulting certain typeclasses to help out, particularly when you're in GHCi. Otherwise you'd have to do things like 1 + 2 :: Int all the time instead of just 1 + 2. If you give it a type signature it works just fine:

> Main.pure (+ 100) `ap` Main.pure 50 :: ((), Int)
((), 150)

GHC just doesn't have defaulting rules for typeclasses you define yourself (and allowing such behavior would be tricky to get right, otherwise you would have very unexpected outcomes in your programs).

like image 151
bheklilr Avatar answered Sep 21 '22 00:09

bheklilr