Haskell 哈斯克尔&x2B;Yesod:使用持久的WIN';分离插入逻辑;我不编译。无法识别类型

Haskell 哈斯克尔&x2B;Yesod:使用持久的WIN';分离插入逻辑;我不编译。无法识别类型,haskell,yesod,Haskell,Yesod,我是哈斯克尔的新人,来自斯卡拉。我喜欢Haskell,但在使用persistent时,我觉得我在与类型系统作斗争 我的请求:我想将一些插入逻辑分离到它自己的方法中。我不太清楚是哪种类型,还是正确的方法。我所有失败的尝试都无法编译。下面是更简洁的问题 以下是数据声明: share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| Curator name String url String feed S

我是哈斯克尔的新人,来自斯卡拉。我喜欢Haskell,但在使用
persistent
时,我觉得我在与类型系统作斗争

我的请求:我想将一些插入逻辑分离到它自己的方法中。我不太清楚是哪种类型,还是正确的方法。我所有失败的尝试都无法编译。下面是更简洁的问题

以下是数据声明:

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Curator
  name String
  url String
  feed String
  UniqueUrl url
  deriving Show
Article
  url String
  title String
  content String
  curatorId CuratorId Eq
  deriving Show
|]
以下是一个失败的尝试,但无效:

insertArticle :: String -> String -> String -> MaybeT (???)
insertArticle url title content = do
    curatorId <- selectFirst [curatorName ==. "Fake Name"]
    lift $ do
        curator <- curatorId
        insert (Article url title content curator)

insertArticle
的返回类型应该是
SqlPersistM(可能是ArticleId)
,因为它在
SqlPersistM
monad中只返回
插入的文章id或
Nothing

您可以实现以下功能:

insertArticle :: String -> String -> String -> SqlPersistM (Maybe ArticleId)
insertArticle url title content = do
    curatorEntity <- selectFirst [CuratorName ==. "Fake Name"] []
    for curatorEntity $ \(Entity curatorId _) ->
        insert (Article url title content curatorId)
签名有点复杂,但此函数可用于任何后端

顺便说一下,您的
getFeeds
可以简化

getFeeds :: (Functor m, PersistQuery m, PersistMonadBackend m ~ PersistEntityBackend Curator) =>
            m [Curator]
getFeeds = map entityVal <$> selectList [] [Asc CuratorName]
getFeeds::(Functor m、PersistQuery m、PersistMonadBackend m~persistenityBackend Curator)=>
m[馆长]
getFeeds=map entityVal selectList[][Asc管理员姓名]

感谢您的快速响应!您如何找到类型为
SqlPersistT
?每当我冒险使用更通用的
insert
类型时,我都会遇到糟糕的、不可读的类型问题。我仍然习惯于浏览黑客,所以可能我错过了
SqlPersistT
。PS-感谢对
getFeeds
的改进!跟进:你知道我在哪里可以阅读更多关于类型签名中波浪(
~
)的信息吗?也就是说,
PersistMonadBackend m
是某种等价物或家族的
persistenitybackend-Curator
?@weirdcanada:
a~b
是一个类型相等约束,意味着
a
b
的类型必须相同。文档:以
getFeeds
为例。我们通常使用
runDB
内部处理程序运行此操作,因此
getFeeds
的具体类型应该是
YesodDB App[Curator]
。如果您查看一下
实例YesodPersist应用程序的定义,就会发现它已扩展为
sqlpersist(HandlerT-App-IO)[Curator]
。这意味着此操作将在
SqlPersistT m
monad中运行。@snak谢谢。我在yesod web应用程序的上下文之外使用它,所以这是有意义的。
insertArticle :: (Applicative m, PersistQuery m, PersistMonadBackend m ~ PersistEntityBackend Curator) =>
                 String -> String -> String -> m (Maybe ArticleId)
getFeeds :: (Functor m, PersistQuery m, PersistMonadBackend m ~ PersistEntityBackend Curator) =>
            m [Curator]
getFeeds = map entityVal <$> selectList [] [Asc CuratorName]