Haskell 如何解决我的GADTs中的歧义
我有两个GADT用于对SQL EDSL建模。为了保持面向客户机的api干净和简单,我想使用Haskell 如何解决我的GADTs中的歧义,haskell,types,dsl,gadt,Haskell,Types,Dsl,Gadt,我有两个GADT用于对SQL EDSL建模。为了保持面向客户机的api干净和简单,我想使用重载字符串将字符串文本强制转换为列选择 因此,您可以简单地键入 select ["a", "b"] $ from tbl 而不是 select [Column "a", Column "b"] $ from tbl 问题是select同时允许列选择s和缩减s 允许执行聚合的查询 mean :: Column Selection -> Column Reduction select :: [Col
重载字符串
将字符串文本强制转换为列选择
因此,您可以简单地键入
select ["a", "b"] $ from tbl
而不是
select [Column "a", Column "b"] $ from tbl
问题是select同时允许列选择
s和缩减
s
允许执行聚合的查询
mean :: Column Selection -> Column Reduction
select :: [Column a] -> Query b -> Query Selection
select [mean "a"] $ from tbl
因此,在[列a]
的上下文中,字符串是不明确的。
但是select[mean“a”]$from tbl
是有效的,因为mean
提供了必要的上下文来推断字符串文本是一个列选择
有人能推荐一种摆脱这种混乱局面的方法吗
下面是我的当前代码(省略了不相关的实例)
我还想使以下签名在选择
/更新
时失败:
[Column Selection] -> Query Reduction -> Query Selection
但是那是一整罐蠕虫……编译器正确地为
Select[“a”]
提供了一个不明确的类型错误-只有在Column
的参数事先已知为Selection
时,才能选择IsString(Column Selection)
实例。这正是我们想要的行为
您需要的是以下内容:
instance (x ~ Selection) => IsString (Column x) where
fromString = Column
这将允许编译器推断“x”::列
实际上必须是“x”::列选择
,而不是要求它
Select[mean“a”]
是一种完全不同的情况-因为mean::Column Selection->Column reduce
,编译器在实例选择发生之前就知道“a”::Column Selection
,因为mean
的类型强制这种情况发生 mean“a”
typechecks与此代码正好匹配,而“a”
的推断类型正是列的选择。然后Select[mean“a”]
的类型是Query b->Query'Selection
。如果有些东西不起作用,请准确地包括导致歧义的表达式以及实际错误是什么。您没有从任何地方定义或tbl
,因此可能错误与这些函数有关。对,但是select[“a”]$from tbl
不进行打字检查。from=Table
和tbl=Schema{name=Just“tbl”,spec=[列“a”,列“b”}
可能:select::[列选择]->查询b->查询选择;减少::[列减少]->查询b->查询选择;选择=选择;reduce=选择
。
instance (x ~ Selection) => IsString (Column x) where
fromString = Column