本文介绍了为什么此代码与Yesod.Persist的get404一起使用,但不是getBy404?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 share [mkPersist sqlSettings,mkMigratemigrateAll ] [坚持| Dog 名称Text 品种Text UniqueDog名称 |] 我有以下路线: mkYesodDogApp[parseRoutes | / RootR GET / dog / name /#Text DogNameR GET / dog / id /#DogId DogIdR GET |] 我试着创建一个页面,返回给定名称的狗的品种。我可以通过getDogIdR路由在URL中使用Id来做到这一点: getDogIdR :: DogId - > Handler RepHtml getDogIdR dogId = do dog< - runDB $ get404 dogId defaultLayout $ do [whamlet | < p> < b>#{dogName dog} < p> #{dogBreed dog} |] 但是,如果我尝试创建与getDogNameR路由相同的页面, getDogNameR :: Text - > Handler RepHtml getDogNameR maybeDogName = do dog< - runDB $ getBy404(UniqueDog maybeDogName) defaultLayout $ do [whamlet | < p> < b>#{dogName dog} < p> #{dogBreed dog} |] 出现以下错误: dog.hs:73:20:无法与`DogGeneric'$ b匹配`Entity'类型$ b在`getBy404'调用的返回类型中在`($)'的第二个参数中,即`getBy404(UniqueDog maybeDogName)'在'做'块:狗< - runDB $ getBy404(UniqueDog maybeDogName) dog.hs:73:20:匹配类型时不兼容: backend0 ::(* - > *) - > * - > * DogGeneric SqlPersist :: * 在`getBy404'调用的返回类型中在`($)'的第二个参数中,即`getBy404(UniqueDog maybeDogName )'在'do'块的标记中: dog 为什么会失败,我该如何解决它? get404和getBy404函数似乎返回不同的类型。如果我按如下方式更改getDogNameR路由,它会运行得很好: getDogNameR :: Text - > Handler RepHtml getDogNameR maybeDogName = do dog< - runDB $ getBy404(UniqueDog maybeDogName) defaultLayout $ do [whamlet | < p> < b>找到了狗! | 解决方案 正确。 get404 ::(PersistStore(tm),PersistEntity val,Monad(tm),m〜GHandler子主, MonadTrans t,PersistMonadBackend(tm)〜PersistEntityBackend val ) =>键val - > tm val $ b getBy404 ::(PersistUnique(tm),PersistEntity val,m〜GHandler子主, Monad(tm),MonadTrans t,PersistEntityBackend val〜PersistMonadBackend(tm)) =>独特的val - > tm(实体val) 所以 getBy404 返回你的狗裹在 实体 ,您拥有 get404 中的纯狗,如果您更换了第二个代码, < b>#{dogName dog} with < b>#{dogName(entityVal dog)} 以及类似的 dogBreed ,或者更多方便的话,如果你解析返回的实体绑定 实体{entityVal = dog}< - runDB $ getBy404 ... Let's say I have a table of dog names and breeds as follows:share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|Dog name Text breed Text UniqueDog name|]I have the following routes:mkYesod "DogApp" [parseRoutes|/ RootR GET/dog/name/#Text DogNameR GET/dog/id/#DogId DogIdR GET|]And I'm trying to create a page that returns the breed of the dog given it's name. I can do this with the Id in the URL via the getDogIdR route just fine:getDogIdR :: DogId -> Handler RepHtmlgetDogIdR dogId = do dog <- runDB $ get404 dogId defaultLayout $ do [whamlet|<p> <b>#{dogName dog}<p> #{dogBreed dog}|]However, if I try creating the same page with the getDogNameR route,getDogNameR :: Text -> Handler RepHtmlgetDogNameR maybeDogName = do dog <- runDB $ getBy404 (UniqueDog maybeDogName) defaultLayout $ do [whamlet|<p> <b>#{dogName dog}<p> #{dogBreed dog}|]I get the following error:dog.hs:73:20: Couldn't match type `Entity' with `DogGeneric' In the return type of a call of `getBy404' In the second argument of `($)', namely `getBy404 (UniqueDog maybeDogName)' In a stmt of a 'do' block: dog <- runDB $ getBy404 (UniqueDog maybeDogName)dog.hs:73:20: Kind incompatibility when matching types: backend0 :: (* -> *) -> * -> * DogGeneric SqlPersist :: * In the return type of a call of `getBy404' In the second argument of `($)', namely `getBy404 (UniqueDog maybeDogName)' In a stmt of a 'do' block: dog <- runDB $ getBy404 (UniqueDog maybeDogName)Why does this fail, and how can I fix it?It appears that the get404 and getBy404 functions return different types. If I change the getDogNameR route as follows, it runs just fine:getDogNameR :: Text -> Handler RepHtmlgetDogNameR maybeDogName = do dog <- runDB $ getBy404 (UniqueDog maybeDogName) defaultLayout $ do [whamlet|<p> <b>Dog found!|] 解决方案 It appears that the get404 and getBy404 functions return different types.Right.get404 :: (PersistStore (t m), PersistEntity val, Monad (t m), m ~ GHandler sub master, MonadTrans t, PersistMonadBackend (t m) ~ PersistEntityBackend val) => Key val -> t m valgetBy404 :: (PersistUnique (t m), PersistEntity val, m ~ GHandler sub master, Monad (t m), MonadTrans t, PersistEntityBackend val ~ PersistMonadBackend (t m)) => Unique val -> t m (Entity val)So getBy404 returns your dog wrapped in an Entity where you have the pure dog from get404, and your second codeshould work if you replace<b>#{dogName dog}with<b>#{dogName (entityVal dog)}and similarly for the dogBreed, or, more conveniently, if you deconstruct the returned Entity on bindingEntity{entityVal = dog} <- runDB $ getBy404 ... 这篇关于为什么此代码与Yesod.Persist的get404一起使用,但不是getBy404?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 11-02 02:28