0

I'm reading through this paper and it says that Monoids are phantom applicative functors.

I tried setting up a phantom type in purescript but I get a type error in the Functor instance. My guess is the compiler doesn't know what the a is in Accy o a after doing the map. How would I fix that?

newtype Accy o a = Accy { acc :: o }

instance mapaccy :: (Monoid o) => Functor (Accy o) where
  map f (Accy { acc : a }) = Accy { acc : (f a) }

instance maccy :: (Monoid o) => Apply (Accy o) where
  apply (Accy { acc : f }) (Accy { acc : a }) = (Accy { acc : f <> a })

instance mpp :: (Monoid o) => Applicative (Accy o) where
  pure _ = Accy { acc : mempty }

instance msemi :: (Monoid o) => Semigroup (Accy o a) where
  append (Accy { acc : a }) (Accy { acc : b }) = Accy { acc : (a <> b) }


map f (Accy { acc : a }) = Accy { acc : (f a) }
                                           ^
  Could not match type      
    o2      
  with type      
    a0      
  while checking that type t1
    is at least as general as type a0
  while checking that expression a
    has type a0
  in value declaration mapaccy
Albtzrly
  • 924
  • 1
  • 6
  • 15
  • 1
    `Accy o` is a constant functor. `map`ing any function `f : a->b` would yield `map f :: Accy o a -> Accy o b` which should ignore `f` completely, since there's no argument of type `a` around (only `o` is available). – chi May 13 '17 at 16:31

1 Answers1

3

I see my problem. The map function is mapping over Accy o so the a in map :: (a -> b) -> f a -> f b is the phantom type which is inaccessable.

Looks like I need to disregard the f in the Functor instance.

instance mapaccy :: (Monoid o) => Functor (Accy o) where
  map f (Accy { acc : a }) = Accy { acc : a }
Albtzrly
  • 924
  • 1
  • 6
  • 15