gpt4 book ai didi

haskell - 如果函数的参数中未使用类型,如何指定函数的类型?

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

我正在使用持久性编写一些数据访问例程。我希望我的 API 根据表示 JSON 的数据类型来定义,但在持久性方面,我的数据类型是由持久性的模板系统定义的。

鉴于我有从 json 到数据库数据类型的映射,反之亦然,我认为我应该能够编写通用的数据访问例程。

一切都很顺利,直到我尝试编写插入函数:

standardInsert :: forall d . forall j .
(PersistEntityBackend d ~ SqlBackend, PersistEntity d, SimpleJsonDataAccessConversion j d)
=> j -> DatabaseEnvironmentT (Maybe (WithId j))
standardInsert json = do
maybeId <- runSqlMaybe $ insert db
return $ toApi <$> maybeId
where db = jsonToDataAccess json :: d -- Scoped type variable here.
toApi key = addId key $ dataAccessToJson db

( j 是 JSON 数据类型的类型变量,d 是持久数据类型的类型变量)。

该函数有两个类型变量,jd ,但只有 j可以从论证中推断出来。

换句话说,如果我调用standardInsert jsonValue ,类型变量d是有歧义的。

我想像在 C++ 中那样调用它 - standardInsert<FooJsonType, FooPersistentType>(jsonValue) .

我如何告诉 Haskell 什么 d是?还是我以完全错误的方式处理这个问题?

最佳答案

GHC 将无法推断类型变量 d。您需要通过添加虚拟参数将其添加到类型签名本身。标准技巧是为这个虚拟参数使用代理,这意味着调用者不需要给出该类型的实际值。

您可以从 tagged 获取代理 GHC <7.8 的软件包,或来自 base对于 GHC>=7.8,但为了解释的目的,我将在这里明确定义它:

data Proxy a = Proxy

standardInsert :: forall d . forall j .
(PersistEntityBackend d ~ SqlBackend,
PersistEntity d, SimpleJsonDataAccessConversion j d)
=> Proxy d -> j -> DatabaseEnvironmentT (Maybe (WithId j))
standardInsert _ json = do (...)

然后在调用站点:

standardInsert (Proxy :: Proxy FooPersistentType) jsonValue

关于haskell - 如果函数的参数中未使用类型,如何指定函数的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24663949/

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