我尝试使用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
?
答案 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
版本与之冲突)