Skip to content

Expand the Wear type family a bit #28

Description

@lspitzner

Greetings!

question

Is there any chance to expand the type family like this:

type family Wear t f a where
  Wear Bare    f (First a) = a
  Wear Bare    f (Last a) = a
  Wear Bare    f a = a
  Wear Covered f a = f a
  Wear (Param _ t) f a = Wear t f a
  Wear t       _ _ = TypeError (     'Text "`Wear` should only be used with "
                               ':<>: 'Text "`Bare` or `Covered`."
                               ':$$: 'Text "`" ':<>: 'ShowType t ':<>: 'Text "`"
                               ':<>: 'Text " is not allowed in this context."
                               )

(This also requires two new instances, of course:

instance GBare n (Rec (P n Identity (Last a)) (Identity (Last a))) (Rec a a) where
  gstrip _ = coerce
  {-# INLINE gstrip #-}

  gcover _ = coerce
  {-# INLINE gcover #-}

)

motivation

use-case is that for combining configs I have f ~ Option, and together with a ~ Last X this gives nice behaviour for generic Semigroup instances. So you'd have a

MyConfig t f = MyConfig
  { a :: Wear t f (Last Bool)
  , b :: Wear t f [Text]
  }

config1 :: MyConfig Covered Option
config2 :: MyConfig Covered Option
staticConfig :: MyConfig Covered Identity
fromOptionIdentity :: Identity a -> Option a -> Identity a
fromOptionIdentity x y = coerce (fromMaybe (coerce x) (coerce y)
finalConfig = bstrip (bzipWith fromOptionIdentity staticConfig (config1 <> config2))
-- (~~see the next issue for what bZipWith is supposed to be~~
--  nevermind, there is a bzipWith already)
-- and have
a finalConfig :: Bool
b finalConfig :: [Text]
-- instead of
a finalConfig :: Last Bool -- pesky left-over from the config merging logic

discussion

We cannot abstract over the type family (yet) so putting this in here is the only way to get this feature, I fear. The downside is that this is a bit confusing behaviour "why does this remove my First/Last wrapper" but then I don't think there are any users who have barbies over First/Last values, apart from this usecase.. it is a bit of a hack.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions