Я хочу использовать GADT как возвращаемое значение стека трансформаторов монад mtl, но GADT имеет тип * -> *, если он не ограничен одним типом. Стек mtl требует * и поэтому не компилируется.
У меня есть стек монадных трансформаторов:
type ExceptStackCornerPointsBuilder = ExceptT String (StateT BuilderStateData (IO)) BuilderMonadData
Возвращаемый тип BuilderMonadData имеет несколько конструкторов, которые должны взаимодействовать друг с другом:
data BuilderMonadData_GADT t where
BuilderMonadData_GPointIds_GADT :: [GPointId] -> BuilderMonadData_GADT
BuilderMonadData_CPoints_GADT :: [CPts.CornerPoints] -> BuilderMonadData_GADT [CPts.CornerPoints]
BuilderMonadData_Points_GADT :: [Pts.Point] -> BuilderMonadData_GADT [Pts.Point]
Я хочу использовать GADT, чтобы ограничить их взаимодействие, но я не могу, поскольку стек требует *, но использование, но использование BuilderMonadData_GADT приводит к * -> *, и поэтому он не компилируется.
Чтобы получить *, мне нужно ограничиться одним конструктором BuilderMonadData_GADT, но я не могу, поскольку все они требуются. У меня уже есть и я использую BuilderMonadData без GADT, и это работает, но я могу ловить только плохие комбинации конструкторов во время выполнения, используя сопоставления с образцом и throwE из ExceptT.
Есть ли способ, используя GADT или какой-либо другой метод, чтобы эти ограничения были обнаружены во время компиляции, при этом все еще используя ADT с несколькими конструкторами и типами?
Код находится по адресу github.com/heathweiss/ChampCad, но я до сих пор не вставил этот код в GADT, и вряд ли какое-то время создаст основную ветвь. Если бы я попросил, я мог бы получить это там.
Версии без GADT находятся по адресу:
https://github.com/heathweiss/ChampCad/blob/master/src/GMSH/Common.hs
а также
https://github.com/heathweiss/ChampCad/blob/master/src/GMSH/Builder/Base.hs