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?
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.