Skip to content

Instantly share code, notes, and snippets.

@Philonous
Last active April 13, 2017 15:31
Show Gist options
  • Select an option

  • Save Philonous/9c5dd1943125aa3758d97d705aa730b5 to your computer and use it in GitHub Desktop.

Select an option

Save Philonous/9c5dd1943125aa3758d97d705aa730b5 to your computer and use it in GitHub Desktop.
api question

My dbus-library has a type for DBus types like this

data DBusSimpleType
    = TypeByte
    | TypeBoolean
    | TypeInt16
    | TypeUInt16
    [...]

data DBusType
    = DBusSimpleType DBusSimpleType -- ^ A simple type
    | TypeArray DBusType -- ^ Variable-length homogenous arrays
    | TypeStruct [DBusType] -- ^ Structs (Tuples) and a list of member types
    [...]

DBus values are encoded as a GADT:

data DBusValue :: DBusType -> * where
    DBVByte       :: Word8         -> DBusValue ('DBusSimpleType TypeByte)
    DBVBool       :: Bool          -> DBusValue ('DBusSimpleType TypeBoolean)
    DBVInt16      :: Int16         -> DBusValue ('DBusSimpleType TypeInt16)
    DBVUInt16     :: Word16        -> DBusValue ('DBusSimpleType TypeUInt16)
    [...]

I also have a Type class for marshalling Haskell types:

class SingI (RepType a) => Representable a where
    -- | The 'DBusType' that represents this type
    type RepType a :: DBusType
    -- | Conversion from Haskell to D-Bus types
    toRep :: a -> DBusValue (RepType a)
    -- | Conversion from D-Bus to Haskell types.
    fromRep :: DBusValue (RepType a) -> Maybe a

with instances for Text, Int8 etc. and template haskell to automatically create representations for complex types.

There is a call function that calls dbus methods and can return values. The question is: Should it

  1. Return the DBusValue (almost never what you want)
  2. Marshal to Haskell via fromRep (convenient, but often requires type anotations because of non-injectivity of RepType)
  3. Marshal to a uniquely selected Haskell type (makes Representable useless but avoids type anotations)

The burden of writing annotations in 2 can be lessened by a newtype that fixed the type and only needs to be pattern matched on, that is, the following never needs a type annotation, even when result is used a polymorphic setting:

 R result <- call [...]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment