Why does this need to be a monoid?

Hello, Im back and in need of help.

I have created a function with the intent of outputting an array of tuples of a key and an object. However whenever I try to use any properties from the object I get an error stating that No type class instance was found for Data.Monoid.Monoid MediaRSSKey or No type class instance was found for Data.Monoid.Monoid Screenfeed. I understand that the objects are not monoids but I dont understand why it is required for them to be one in the first place. Below I will include the problem function, a similar function that works as well as some object definitions. I could really use some help on this. Let me know if you need more because I have been working on this for nearly 3 days now and Im at the end of my patience and will take any assistance.

Problem function

getInnerZoneMedias ∷ Edict β†’ CatArray (Tuple MediaRSSKey Screenfeed)
getInnerZoneMedias (Edict {playlists}) = 
 flip foldMap playlists \(Playlist {key, media}) β†’
    flip foldMap media \(MuMedia (MediaMeta { particular })) β†’
            (on symContentDesigner (\(ContentDesigner {zones}) β†’
              flip foldMap zones \(Zone {media}) β†’ 
                CatArray.fromArray (flip map media \(MuMedia (MediaMeta { particular })) β†’
                  (on symScreenfeed (\(Screenfeed x) β†’
                    Tuple x.rssKey (Screenfeed x)
                  )
                  $ (\_ β†’ mempty)) particular  ← ERROR APPEARING HERE
                )
              )
            $ (\_ β†’ mempty)) particular

Working Function:

getZoneMedias ∷ Edict β†’ CatArray (Tuple PlaylistKey (CatArray MuMedia))
getZoneMedias (Edict {playlists}) = 
 flip foldMap playlists \(Playlist {key, media}) β†’
    flip foldMap media \(MuMedia (MediaMeta { particular })) β†’
            (on symContentDesigner (\(ContentDesigner {zones}) β†’
              CatA.fromArray (flip map zones \(Zone z) β†’ Tuple z.key (CatA.fromArray z.media))
              )
            $ (\_ β†’ mempty)) particular

Zone and Screenfeed defs:

newtype Screenfeed = Screenfeed
  { rssKey ∷ MediaRSSKey
  , playAll ∷ Boolean
  , expireDays ∷ Days
  , hideAnimation ∷ Boolean
  , hideDescription ∷ Boolean
  , hideTitle ∷ Boolean
  , lineColour ∷ String
  , backgroundColour ∷ String
  , descriptionColour ∷ String
  , titleColour ∷ String
  , font ∷ String
  , overlayStyleId ∷ Int
  }
--

derive instance newtypeScreenfeed ∷ Newtype Screenfeed _

derive instance genericScreenfeed ∷ Generic Screenfeed _

derive newtype instance eqScreenfeed ∷ Eq Screenfeed

derive instance ordScreenfeed ∷ Ord Screenfeed

instance showScreenfeed ∷ Show Screenfeed where
  show = genericShow
--

symScreenfeed ∷ SProxy "screenfeed"
symScreenfeed = SProxy

newtype Zone media =
  Zone
  { key ∷ PlaylistKey
  , media ∷ Array media
  , randomise ∷ Boolean
  , timelineMeta ∷ Maybe PlaylistTimelineMeta
  }
--

derive instance newtypeZone ∷ Newtype (Zone media) _

derive instance zoneGeneric ∷ Generic (Zone media) _

instance zoneShow ∷ Show media β‡’ Show (Zone media) where
  show = genericShow
--

derive newtype instance zoneEq ∷ Eq media β‡’ Eq (Zone media)

derive instance eq1Zone ∷ Eq1 Zone

-- | access to the media property
_media ∷ βˆ€ a b. Lens (Zone a) (Zone b) (Array a) (Array b)
_media = _Newtype <<< prop (SProxy∷_"media")

Hi @ldebort!
Let me zoom in on this part:

I think you’re using on from the variant package, and I can see the definition is

on :: forall sym a b r1 r2. Cons sym a r1 r2 => IsSymbol sym => 
  Proxy sym -> (a -> b) -> (Variant r1 -> b) -> Variant r2 -> b

So your second argument (which must be type a -> b) returns a Tuple MediaRSSKey Screenfeed. Your third argument (which must be type Variant r1 -> b) returns mempty, which is a Monoid.
Since both return values must be type b, they have to be the same type, or in other words Tuple MediaRSSKey Screenfeed must be a monoid. Turns out a Tuple is a monoid as long as both components are monoids. So the 2nd and 3rd arguments can be returning the same type so long as MediaRSSKey and Screenfeed are both monoids.

To get around that particular error, you’ll have to make the fallback case for your variant return a Tuple MediaRSSKey Screenfeed instead of mempty. What tuple should be used in the event that the variant value in particular is not symScreenfeed?

2 Likes

Ayy. That works. Makes sense as well. Thank you so much for your help. I really need to sit down and actually learn what a lot of this terminology actually means in the context of purescript.

1 Like