我看过一些类似主题的帖子,但它们并没有真正帮助我解决我的问题。所以我敢重复。
现在我有一个带有签名的函数:
run' :: Expr query => RethinkDBHandle -> query -> IO [JSON]
这是一个数据库查询运行功能。
我将此函数包装在一个池中(池已创建且与问题无关)以简化连接。
rdb q = withResource pool (\h -> run' (use h $ db "test") q)
本质上,此函数与上面的运行具有完全相同的签名。
问题是,如果我使用没有签名的函数,那么一切都很好,GHC 很乐意解决问题。一旦我指定签名,它就会停止处理某些输入,抱怨无法推断出类型。
主要有两种输入类型用作查询输入。
ReQL and Table
这两种类型都是实例,Expr
因此它们都被 GHC 接受。
一旦我输入签名,一切都停止工作,GHC 抱怨无法推断类型并给我“类型签名绑定的刚性类型变量”错误。如果我让签名更具体,ReQL
而不是Expr a
,那么显然它会停止接受Table
输入,反之亦然。将输入指定为Expr a
和的实例,会因上述错误而停止ReQL
。Table
将签名全部删除可以正常工作。
那么我该如何解决呢?放弃签名感觉不对。
我不知道我是否应该使问题更通用或更具体,但如果它有帮助,这是一个包含所有类型和实例的库,可以帮助提供建议。
更新
根据要求,这是产生错误的完整代码清单。
main = do
pool <- createPool (connect "localhost" 28015 Nothing) close 1 300 5
let rdb q = withResource pool (\h -> run' (use h $ db "test") q)
scotty 3000 $ basal rdb
basal :: Expr q => (q -> IO [JSON]) -> ScottyM ()
basal r = get "/json" $ showJson r
showJson :: Expr q => (q -> IO [JSON]) -> ActionM ()
showJson r = do
j <- lift $ r $ table "mytable"
text $ T.pack $ show j
这是完整的错误列表
Main.hs:19:17:
No instance for (Expr q0) arising from a use of `basal'
The type variable `q0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Expr () -- Defined in `Database.RethinkDB.ReQL'
instance (Expr a, Expr b) => Expr (a, b)
-- Defined in `Database.RethinkDB.ReQL'
instance (Expr a, Expr b, Expr c) => Expr (a, b, c)
-- Defined in `Database.RethinkDB.ReQL'
...plus 24 others
In the second argument of `($)', namely `basal rdb'
In a stmt of a 'do' block: scotty 3000 $ basal rdb
In the expression:
do { pool <- createPool
(connect "localhost" 28015 Nothing) close 1 300 5;
let rdb q = withResource pool (\ h -> ...);
scotty 3000 $ basal rdb }
Main.hs:26:19:
Could not deduce (q ~ Table)
from the context (Expr q)
bound by the type signature for
showJson :: Expr q => (q -> IO [JSON]) -> ActionM ()
at Main.hs:24:13-52
`q' is a rigid type variable bound by
the type signature for
showJson :: Expr q => (q -> IO [JSON]) -> ActionM ()
at Main.hs:24:13
In the return type of a call of `table'
In the second argument of `($)', namely `table "mytable"'
In the second argument of `($)', namely `r $ table "mytable"'
谢谢