为什么此代码与Yesod.Persist的get404一起使用,但不是getBy404? [英] Why does this code work with Yesod.Persist's get404 but not getBy404?

查看:133
本文介绍了为什么此代码与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 < - runDB $ getBy404(UniqueDog maybeDogName)

为什么会失败,我该如何解决它?



get404和getBy404函数似乎返回不同的类型。如果我按如下方式更改getDogNameR路由,它会运行得很好:

  getDogNameR :: Text  - > Handler RepHtml 
getDogNameR maybeDogName = do
dog< - runDB $ getBy404(UniqueDog maybeDogName)
defaultLayout $ do
[whamlet |
< p>
< b>找到了狗!
|


解决方案


<看起来get404和getBy404函数返回不同的类型。

正确。

  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 RepHtml
getDogIdR 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 RepHtml
getDogNameR 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 RepHtml
getDogNameR 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 val

getBy404 :: (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 binding

Entity{entityVal = dog} <- runDB $ getBy404 ...

这篇关于为什么此代码与Yesod.Persist的get404一起使用,但不是getBy404?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆