4
votes

I'm trying to use Persistent with Yesod to get the list of all field keys from a table in my database. My accessor code is as follows:

getMapList :: Handler [Text]
getMapList = runDB $ do
  dbList <- selectList [] []
  return (map getMapName dbList)
  where getMapName (Entity (Key (PersistText mapName)) _)  = mapName

Note that this is a game: "Map" here is a map in the game sense, not in the Haskell sense.

I get the following error, which indicates that the type inference engine can't figure out my types, based on which database backend I'm using.

Handler/Create.hs:101:13:
Couldn't match type `PersistEntityBackend t0'
              with `persistent-1.2.3.0:Database.Persist.Sql.Types.SqlBackend'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: PersistMonadBackend (SqlPersistT (HandlerT App IO))
  Actual type: PersistEntityBackend t0
In a stmt of a 'do' block: dbList <- selectList [] []
In the second argument of `($)', namely
  `do { dbList <- selectList [] [];
        return (map getMapName dbList) }'
In the expression:
  runDB
  $ do { dbList <- selectList [] [];
         return (map getMapName dbList) }

Does anybody know how to fix this? What do I need to add to the type signature to get this to type-check properly? Thanks!

EDIT: My model is defined as such:

GameMap
    mapName Text
    mapCode Text
    UniqueGameMap mapName
    deriving Typeable
1

1 Answers

3
votes

I think you need add the Filter type signature, which is based on the table you defined elsewhere (I am not sure if you were trying to avoid needing to type in the column names somewhere though.... I am not sure if this is possible).

Does this work for you? If the table is defined as-

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
KingsLadiesInWaiting
    name String
    skillLevel Int
    deriving Show
|]

just add-

getMapList :: Handler [T.Text]
getMapList = runDB $ do
  dbList <- selectList ([]::[Filter (KingsLadiesInWaitingGeneric backend)]) []
  return (map getMapName dbList)
  where getMapName (Entity (Key (PersistText mapName)) _)  = mapName

When I did this it compiled.

This should make for an interesting game!