1

次のような犬の名前と品種の表があるとしましょう。

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|
Dog
    name Text
    breed Text
    UniqueDog name
|]

私は次のルートを持っています:

mkYesod "DogApp" [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:
    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)

なぜこれが失敗するのですか、どうすれば修正できますか?

get404関数とgetBy404関数は異なるタイプを返すようです。getDogNameRルートを次のように変更すると、正常に実行されます。

getDogNameR :: Text -> Handler RepHtml
getDogNameR maybeDogName = do 
    dog <- runDB $ getBy404 (UniqueDog maybeDogName)
    defaultLayout $ do
        [whamlet|
<p>
    <b>Dog found!
|]
4

1 に答える 1

4

get404 関数と getBy404 関数は異なる型を返すようです。

右。

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)

したがって、元の純粋な犬を持っている場所にgetBy404包まれた犬を返します.2番目のコードは、Entityget404

<b>#{dogName dog}

<b>#{dogName (entityVal dog)}

同様に、またはより便利に、返されたバインディングdogBreedを分解する場合Entity

Entity{entityVal = dog} <- runDB $ getBy404 ...
于 2012-12-10T00:25:17.110 に答える