haskell - 寻找一种更好的方法来编写一个将类型构造函数作为参数的函数
问题描述
我有一个 Haskell 仆人应用程序。我想从文件中读取并用文件的内容填充数据库。我有的是这个
userList :: IO [User]
productList :: IO [Product]
data User = User { age :: Int, fname :: String, lname :: String }
data Product = Product { title :: String, description :: String }
data Item = UserI User | ProductI Product
listUsers :: Handler [Entity User]
listProducts :: Handler [Entity Product]
hydrateUserDB :: Handler [Entity User]
hydrateUserDB = do
items <- liftIO userList
let list = fmap User items
traverse_ createUser list
listUsers
hydrateProductDB :: Handler [Entity Product]
hydrateProductDB = do
items <- liftIO productList
let list = fmap Product items
traverse_ createProduct list
listProducts
现在我想要一个可以使用 User 或 Product 并产生与上面类似的结果的函数。就像是:
hydrateDB :: Handler [Entity a]
hydrateDB =
\alist con createItem listItems -> do
items <- liftIO alist
let list = fmap con items
traverse_ createItem list
listItems
解决方案
这可能是类型类的一个很好的用途。把从一个版本到另一个版本不同的东西放在一个类中。设计可能会有所改进,但这是第一步:
class DBItem a where
itemList :: IO [a]
createItem :: a -> Handler ()
listItems :: Handler [Entity a]
instance DBItems User where
itemList = userList
createItem = ...
listItems = listUsers
instance DBItems Product where
itemList = productList
...
hydrateDB :: (DBItem a) => Handler [Entity a]
hydrateDB = do
items <- liftIO itemList
traverse_ createItem items
listItems
(我做了一些更改以使类型有意义,但你明白了)
推荐阅读
- php - 如何通过访问器将其他字段添加到最终 JSON 中?
- javascript - 如何在 wdio junit 报告器 xml 报告中显示跳过的消息
- swift - Swift:动画约束在不同的设备上产生不同的结果
- python - Discord.py 设置用户 ID 作为参数
- swift - 从 Firestore 返回文档的 Swift 函数
- ios - Firebase 动态链接不适用于 HTML 电子邮件。仅限ios
- c++ - ETW - 事件跟踪的实时消耗
- javascript - 如何将formarray重置为角度中的一项
- linux - 当我的 linux 会话超时时如何不让我的进程消失
- ios - 无法在 Xcode 中导入模块 app_setings - Flutter