Albtzrly
Albtzrly

Reputation: 934

How to make a phantom applicative functor in PureScript?

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

Upvotes: 0

Views: 151

Answers (1)

Albtzrly
Albtzrly

Reputation: 934

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 }

Upvotes: 3

Related Questions