Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如果函数';谁的论点?_Haskell_Type Inference - Fatal编程技术网

Haskell 如果函数';谁的论点?

Haskell 如果函数';谁的论点?,haskell,type-inference,Haskell,Type Inference,我正在编写一些数据访问例程,使用持久化。我想用表示JSON的数据类型来定义API,但在持久性方面,我的数据类型是由持久性的模板系统定义的 鉴于我有从json到数据库数据类型的映射,反之亦然,我认为我应该能够编写通用的数据访问例程 在我尝试编写插入函数之前,一切都进展顺利: standardInsert :: forall d . forall j . (PersistEntityBackend d ~ SqlBackend, PersistEntity d,

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

鉴于我有从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
standardsert::forall d。福尔j。
(persistenitybackend d~SqlBackend、persistenty d、SimpleJsonDataAccessConversion j d)
=>j->DatabaseEnvironmentT(可能(使用id j))
standardInsert json=do

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

对于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

从GHC 7.8开始,
Data.Proxy
实际上位于
base
中。与其指定函数采用
Proxy d
,我更喜欢使用
pd
参数。在这类代码中,很常见的情况是已经有了与该类型匹配的可用内容,因此可以直接使用预先存在的值,而我更喜欢显式编写
Proxy::d
。太棒了,非常感谢!我开始觉得我可能已经有点喜欢类型类了,也许我应该抛弃
SimpleJsonDataAccessConversion jd
,只传递一个包含
j->d
d->j
方法的数据结构。不过,我很想知道这是否可行。非常感谢您提供了一个非常清晰的答案。@JohnL显然这是一个风格/品味的问题,因此意见会有所不同,但我更愿意明确地说,传入的值对计算没有影响。@GaneshSittampalam将其编写为
代理d
,这有助于使其更清晰。如果您熟悉参数,您很容易就会发现,如果函数类型中没有出现
proxy
类型的参数,则不能使用
proxy d
类型的参数。