1

With the following Persistent schema,

Picture
  bytes ByteString
  desc Text Maybe

I want to query SELECT id, desc FROM picture WHERE desc IS NOT NULL. But

previews :: SqlPersistT Handler [(E.Value (Key Picture), E.Value Text)]
previews = E.select $ from $ \pics -> do
  where_ $ pics ?. PictureDesc E.!=. nothing
  return ( pics ^. PictureId
         , pics ?. PictureDesc
         )

• Couldn't match type ‘Maybe (Entity Picture)’
                 with ‘Entity Picture’
  Expected type: SqlExpr (Entity Picture)
    Actual type: SqlExpr (Maybe (Entity Picture))
• In the first argument of ‘(^.)’, namely ‘pics’

How do I achieve the previews' signature?

jeiea
  • 1,965
  • 14
  • 24

1 Answers1

0

You tried to use the (?.) operator to get a non-Maybe Value from a Maybe field in a non-Maybe entity, but what it does is to get you a Maybe Value from a non-Maybe field in a Maybe entity. Here, your entity actually isn't Maybe because it isn't the result of an outer join.

I don't think returning a Value Text is possible without unsafe functions, since filtering with where_ doesn't change the type of the nullable field to be non-nullable. (There ought to be a projection operator that does what you want to do, in my opinion.)

So you could do this

previews :: SqlPersistT Handler [(Value (Key Picture), Value (Maybe Text))]
previews = select $ from $ \pics -> do
  where_ $ not_ . isNothing $ pics ^. PictureDesc
  return ( pics ^. PictureId
         , pics ^. PictureDesc
         )

or remove the Maybe, using Control.Arrow's second and Data.Maybe's fromJust, although there might be a more elegant way:

previews' :: SqlPersistT Handler [(Value (Key Picture), Value Text)]
previews' = do
  xs <- select $ from $ \pics -> do
    where_ $ not_ . isNothing $ pics ^. PictureDesc
    return ( pics ^. PictureId
           , (pics ^. PictureDesc)
           )
  return (map (second $ fmap fromJust) xs)

I haven't run this code, only compiled it.

nnnmmm
  • 7,964
  • 4
  • 22
  • 41