Skip to content

Unify Async APIs #55

@hyperthunk

Description

@hyperthunk

Trying to unify the APIs for AsyncChan and AsyncSTM in d-p-platform. I've thought about doing this with type (or data) families but ... we need to handle AsyncChan a or AsyncSTM a so...

class Async a where
  type AsyncHandle a :: *
  poll :: AsyncHandle a -> Process (AsyncResult b)
  wait :: AsyncHandle a -> Process (AsyncResult b)
  ... etc

but ...

instance Async (STM.AsyncSTM a) where
  type AsyncHandle (STM.AsyncSTM a) = STM.AsyncSTM a
  poll = STM.poll
  wait = STM.wait

this isn't quite what I want, as the types cannot be inferred properly. And I couldn't quite figure out whether declaring data AsyncHandle a in the type class and having the instance as data AsyncHandle (STM.AsyncSTM a) = HStm (STM.AsyncSTM a) was the right approach either, but of course you can't leave a gap in the type signature without telling the compiler what the relation is between the two:

instance Async (STM.AsyncSTM a) where
  data AsyncHandle (STM.AsyncSTM a) = HStm (STM.AsyncSTM a)
  poll (HStm h) = STM.poll h  -- illegal because we don't know that the `a` in the associated type is related to the `a` in the instance declaration. 

I wondered about functional dependencies here, but couldn't see how to apply them. Anyhow, I realise this is probably a pretty basic question, but I don't see a neat way to handle it. Should I just live with having the two APIs without a common method of interchanging between them? At the moment, for the most part all you need to do to switch from AsyncChan to AsyncSTM is change your imports.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions