我有一个 Lift 应用程序,我将其移植到 Yesod,作为学习框架和 Haskell 的一种方式。应用程序的一部分仅驻留在 TCP 和数据库层:解析来自套接字连接的传入字节并将它们转换为更新以供模型处理。我在 Scala 中使用正则表达式和模式匹配进行了此操作,但未能在 Haskell 中重现它。
一个高度简化的例子:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|
Person
name String
deriving Show
UnknownMessage
text String
deriving Show
|]
parseMsg m = runDB $ do
case ms of
["add",name] -> insert Person{personName = name}
["delete",name] -> deleteWhere [PersonName ==. name]
["change",from,to] -> updateWhere [PersonName ==. from] [PersonName =.to]
_ -> insert UnknownMessage{unknownMessageText = m}
where
ms = splitRegex (mkRegex ",") m
上面的代码只会在四个模式匹配中的三个被注释掉的情况下编译。"insert Person" 不能与 "deleteWhere" 一起玩,甚至不能与 "insert UnknownMessage" 一起玩。结果往往是类型匹配的错误消息,我经常无法做出正面或反面。
我该如何重写上面的代码?是否有针对任何地方受到单子挑战的持久指南?本书章节没有详细介绍如何链接查询等。
编辑:hammar 建议在插入中添加 (>>) 解决了这个问题。如果我删除“runDB $ do”,函数的类型变为“parseMsg :: PersistQuery backend m => String -> backend m ()”。这是否允许我稍后在 monad 中执行返回的查询,就像我在 Scala 中处理我的更新一样?