Haskell 如何解决我的GADTs中的歧义

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

我有两个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 :: [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