【发布时间】:2018-05-27 15:09:52
【问题描述】:
我编写了一个简单的 Yesod Rest 服务器,它将实体保存在 JSON 文件中。 实体存储在磁盘上名为 data/type.id.json 的文件中。 例如,retrieveCustomer "1234" 应该从文件 data/Customer.1234.json 加载数据。
我正在使用一个多态函数retrieveEntity,它可以检索任何数据类型的实例,这些数据类型实例化了FromJSON 类型类。 (这部分效果很好)
但目前我必须在类型特定的函数(如retrieveCustomer)中填写硬编码的类型名称。
如何在通用的retrieveEntity 中动态计算类型名称? 我想我基本上是在寻找迄今为止我没有遇到过的 Haskell 类型的反射机制?
-- | retrieve a Customer by id
retrieveCustomer :: Text -> IO Customer
retrieveCustomer id = do
retrieveEntity "Customer" id :: IO Customer
-- | load a persistent entity of type t and identified by id from the backend
retrieveEntity :: (FromJSON a) => String -> Text -> IO a
retrieveEntity t id = do
let jsonFileName = getPath t id ".json"
parseFromJsonFile jsonFileName :: FromJSON a => IO a
-- | compute path of data file
getPath :: String -> Text -> String -> String
getPath t id ex = "data/" ++ t ++ "." ++ unpack id ++ ex
-- | read from file fileName and then parse the contents as a FromJSON instance.
parseFromJsonFile :: FromJSON a => FilePath -> IO a
parseFromJsonFile fileName = do
contentBytes <- B.readFile fileName
case eitherDecode contentBytes of
Left msg -> fail msg
Right x -> return x
【问题讨论】:
标签: haskell reflection yesod