GADT和MTL变压器

时间:2019-07-11 18:07:19

标签: haskell monad-transformers gadt

我想将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.hshttps://github.com/heathweiss/ChampCad/blob/master/src/GMSH/Builder/Base.hs

0 个答案:

没有答案