我想将GADT用作mtl monad变压器堆栈的返回值,但是GADT的类型为*-> *,除非限制为单个类型。 mtl堆栈需要*,因此不会编译。
我有一个monad变压器堆栈:
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构造函数,但我不能,因为它们都是必需的。我已经拥有并使用了不带GADT的BuilderMonadData,它可以工作,但是我只能在运行时使用模式匹配和ExceptT的throwE来捕获构造函数的错误组合。
有没有一种方法可以使用GADT或其他方法在编译时捕获这些约束,同时仍然使用具有多个构造函数和类型的ADT?
该代码位于github.com/heathweiss/ChampCad上,但我仍未将该代码与GADT一起推送,并且暂时不会成为master分支。如果需要的话,我可以到那里去。
不含GADT的版本位于: https://github.com/heathweiss/ChampCad/blob/master/src/GMSH/Common.hs 和 https://github.com/heathweiss/ChampCad/blob/master/src/GMSH/Builder/Base.hs