0

I am trying to make use of the unsafeSqlExtractSubField from Esqueleto to create one that will extract the year from a date, such as:

data ReportRow = ReportRow Text

userSignupData :: MonadIO m => Key User -> SqlPersistT m [ReportRow]
userSignupData _ = fmap toRow <$> select (from query)
  where
    query s =
      pure $ (extractYear $ s ^. UserCreatedAt)

    toRow yearVal = ReportRow (showText . unValue $ yearVal)

extractYear :: UnsafeSqlFunctionArgument a => a -> SqlExpr (Value Integer)
extractYear =
  unsafeSqlExtractSubField "year"

showText :: Show a => a -> Text
showText = T.pack . show

But I am getting the error:

Could not deduce
  (UnsafeSqlFunctionArgument
    (expr0 (Value UTCTime)))

  arising from a use of ‘query’
from the context: MonadIO m
  bound by the type signature for:
    userSignupData :: forall (m :: * -> *).
                      MonadIO m =>
                      Key User -> SqlPersistT m [ReportRow]

The type variable ‘expr0’ is ambiguous

   |
20 | userSignupData _ = fmap toRow <$> select (from query)
   |                                                ^^^^^

Do I need to define an instance of UnsafeSqlFunctionArgument for UTCTime here or am I trying to fit a square peg into a round hole ?

I'm not after answers that state that I could extract the date at the haskell level, I'd like to get the year inside the query so that I can perform an SQL GROUP BY inside the query.

danbroooks
  • 2,712
  • 5
  • 21
  • 43
  • Could you include more of that error? What line does it complain about? – AJF Jun 13 '18 at 13:21
  • This link might be useful for anyone trying to get esqueleto to build while trying to reproduce the error: https://github.com/bitemyapp/esqueleto/issues/88 – Kartik Sabharwal Jun 14 '18 at 14:26
  • I'm not 100% sure but I think the error can be deduced by looking at the type signatures of `(^.)` and `extractYear`. From GHCi, `(^.) :: (PersistField typ, PersistEntity val, Esqueleto query expr backend) => expr (Entity val) -> EntityField val typ -> expr (Value typ)` and from your code, `extractYear :: UnsafeSqlFunctionArgument a => a -> SqlExpr (Value Integer)` where `a` is going to be `expr (Value typ)`. This means there are _no guarantees_ that `expr` is an instance of `UnsafeSqlFunctionArgument` so you get a `Could not deduce...` error. I don't think `UTCTime` matters here. – Kartik Sabharwal Jun 15 '18 at 04:49

0 Answers0