Haskell RethinkDB插入不能返回我想要的类型?

时间:2014-12-17 22:29:34

标签: haskell rethinkdb

我尝试使用User函数将saveUser插入RethinkDB。

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module User where

import Database.RethinkDB
import Data.Text (Text)
import Data.Aeson (FromJSON, ToJSON)
import GHC.Generics
import Database.RethinkDB

saveUser ::  RethinkDBHandle -> User -> IO User
saveUser handle user = run handle $ table "test" # insert
  ["email" := (email user),
  "hash" := (hash user),
  "institutionId" := (institutionId user)]


getAllUsers :: RethinkDBHandle -> IO [User]
getAllUsers handle = run handle $ table "test"


data User = User {
  id :: Maybe String,
  email :: String,
  hash :: String,
  institutionId :: String
} deriving (Show, Generic)

instance ToJSON User
instance FromJSON User
instance ToDatum User
instance FromDatum User
instance Expr User

run函数返回IO Result。从阅读文档开始,Result似乎是Datum,我的User也是Datum,所以我希望能够返回IO User来自这个函数,就像我在IO [User]函数中返回getAllUsers一样。但是,我收到以下错误:

    No instance for (Result User) arising from a use of ‘run’
    In the expression: run handle
    In the expression:
      run handle
      $ table "test"
        # insert
            ["email" := (email user), "hash" := (hash user),
             "institutionId" := (institutionId user)]
    In an equation for ‘saveUser’:
        saveUser handle user
          = run handle
            $ table "test"
              # insert
                  ["email" := (email user), "hash" := (hash user),
                   "institutionId" := (institutionId user)]
Failed, modules loaded: none.

当我将saveUser功能的类型更改回IO Datum时,它再次起作用。当IO User返回run时,Haskell如何推断我的函数无法返回IO Result

1 个答案:

答案 0 :(得分:1)

从文档中可以看出,存在实例

FromDatum a => Result [a]

这解释了为什么getAllUsers函数有效,但

没有实例
FromDatum a => Result a

相反,看起来这个API的作者宁愿使用实例

FromDatum a => Result (Maybe a)

以便在用户插入不当时能够正确处理故障。如果您将功能更改为

saveUser ::  RethinkDBHandle -> User -> IO (Maybe User)
saveUser handle user = run handle $ table "test" # insert
  ["email" := (email user),
  "hash" := (hash user),
  "institutionId" := (institutionId user)]

然后它应该编译得很好。 (我尝试安装rethinkdb,但显然我的network版本与之冲突)