Hey all. I have the following newtype
newtype MakeGraphObject
(hierarchy :: NonEmptyList' Type)
(bindableData :: Row Type)
(graphObjType :: Type)
(a :: Type) =
MakeGraphObject (ReaderT graphObjType Effect a)
-- NonEmptyList is exactly what it sounds like, my implementation:
import Type.Data.List (List')
data NonEmptyList' :: forall k. k -> Type
data NonEmptyList' k
foreign import data ConsNonEmpty' :: Type -> List' Type -> NonEmptyList' Type
infixr 1 type ConsNonEmpty' as :>>
This newtype has that list in order to determine some instances for this monad. The issue I’m trying to address is that the head of this NonEmptyList argument is always the read type graphObjType, and I’m just being careful in every type signature to match them up. What I’d like to do is something like this:
newtype MakeGraphObject
(graphObjType :>> rest :: NonEmptyList' Type)
(bindableData :: Row Type)
(a :: Type) =
MakeGraphObject (ReaderT graphObjType Effect a)
But this syntax is not accepted. I attempted a workaround with existential typing, which seems like a terrible idea anyway, like this:
class Head (xs :: NonEmptyList' Type) (h :: Type) | xs -> h
instance Head (h :>> rest) h
newtype MakeGraphObject
(hierarchy :: NonEmptyList' Type)
(bindableData :: Row Type)
(a :: Type) =
MakeGraphObject (forall @graphObjectType. Head hierarchy graphObjectType => ReaderT graphObjectType Effect a)
But this breaks all kinds of things, including inducing an internal error in the compiler lol. An alternative is to instead use hierarchy
as a simple list and still carry around the extra argument, but it’s just going to look ugly elsewhere in the code… Is this the only way to achieve what I’m looking for?