gpt4 book ai didi

haskell - 如何解决 GADT 中的歧义

转载 作者:行者123 更新时间:2023-12-02 17:25:41 25 4
gpt4 key购买 nike

我有两个 GADT,用于对 SQL EDSL 进行建模。为了使面向 API 的客户端保持干净和简单,我想使用 OverloadedStrings 将字符串文字转换为列选择。

因此您只需输入

select ["a", "b"] $ from tbl

而不是

select [Column "a", Column "b"] $ from tbl

问题是 select 允许同时进行列选择缩减以允许执行聚合的查询。

mean :: Column Selection -> Column Reduction

select :: [Column a] -> Query b -> Query Selection
select [mean "a"] $ from tbl

因此,在[Column a] 的上下文中,字符串是不明确的。但是 select [mean "a"] $ from tbl 是有效的,因为 mean 提供了必要的上下文来推断字符串文字是列选择。

谁能推荐一种摆脱这种困惑的方法吗?

下面是我当前的代码(省略了不相关的实例)

{-# LANGUAGE 
GADTs
, RankNTypes
, DataKinds
, TypeFamilies
, FlexibleContexts
, FlexibleInstances
, OverloadedStrings #-}

data Sz = Selection | Reduction deriving Show
data Schema = Schema{name :: Maybe String, spec :: [Column Selection]}

type family ColOp (a :: Sz) (b :: Sz) where
ColOp Selection Selection = Selection
ColOp Selection Reduction = Selection
ColOp Reduction Selection = Selection
ColOp Reduction Reduction = Reduction

data Column (a :: Sz) where
Column :: String -> Column Selection
Assign :: String -> Column a -> Column a
FKey :: String -> Schema -> Column Selection
BinExpr :: BinOp -> Column a -> Column b -> Column (ColOp a b)
LogExpr :: LogOp -> Column a -> Column b -> Column Selection
AggExpr :: AggOp -> Column Selection -> Column Reduction

instance IsString (Column Selection) where
fromString s = Column s

data Query (a :: Sz) where
Table :: Schema -> Query Selection
Select :: [Column a] -> Query b -> Query Selection
Update :: [Column a] -> Query b -> Query Selection
Where :: [Column Selection] -> Query Selection -> Query Selection
Group :: [Column Selection] -> Query Selection -> Query Reduction

我还想让 Select/Update 的以下签名失败:

[Column Selection] -> Query Reduction -> Query Selection

但这完全是另一回事......

最佳答案

编译器正确地为您提供了 Select ["a"] 的不明确类型错误 - 只能选择 IsString (Column Selection) 实例 如果先验已知Column的参数是Selection。这正是预期的行为。

您想要的是以下内容:

instance (x ~ Selection) => IsString (Column x) where
fromString = Column

这将允许编译器推断 "x"::Column _ 实际上必须是 "x"::Column Selection,而不是要求它。

Select [mean "a"] 是一种完全不同的情况 - 因为 mean::Column Selection -> Column Reduction,编译器知道,在实例选择发生之前, "a"::Column Selection,因为 mean 的类型迫使情况如此。

关于haskell - 如何解决 GADT 中的歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35757157/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com