Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writing utility query callers in Squeal 0.6 #210

Open
adfretlink opened this issue Apr 4, 2020 · 1 comment
Open

Writing utility query callers in Squeal 0.6 #210

adfretlink opened this issue Apr 4, 2020 · 1 comment
Labels

Comments

@adfretlink
Copy link

adfretlink commented Apr 4, 2020

I'm trying to upgrade our set of utilities to prepare the ground for a general upgrade of our codebase to Squeal 0.6. It's going rather well, this release has a lot of great features ! I'm very excited about it.

To spare some keystroke, I like to use a series of small functions like this one (Squeal 0.5):

-- | Run a query and retrieve its first result, that must be
-- an Only x. Use `queryStatement` to call this with a `Query`
-- rather than `Manipulation`.
maybeOneOnly ::
  (MonadUnliftIO m, MonadPQ schema m, ToParams p params, FromValue a b) =>
  Manipulation '[] schema params (OnlyReturns a)
  -- ^ Query to run, that returns a `Only` type
  -> p
  -- ^ Query to run
  -> m (Maybe b)
  -- ^ Maybe a result in the monadic context
maybeOneOnly q p = manipulateParams q p >>= (fmap . fmap) fromOnly . firstRow

I would have loved to be able to express it in Squeal 0.6 using the new type family Manipulation_, like this:

maybeOneOnly' ::
  (MonadUnliftIO m, MonadPQ db m) =>
  Manipulation_ db params (Only r)
  -- ^ Query to run, that returns a `Only` type
  -> params
  -- ^ Query to run
  -> m (Maybe r)
  -- ^ Maybe a result in the monadic context
maybeOneOnly' q p = manipulateParams q p >>= (fmap . fmap) fromOnly . firstRow

Sadly I must be missing something here, as the compiler yells at me:

    • Couldn't match type ‘Generics.SOP.Universe.Code params’
                     with ‘'[TupleCodeOf params (Generics.SOP.Universe.Code params)]’
        arising from a use of ‘manipulateParams’
    • In the first argument of ‘(>>=)’, namely ‘manipulateParams q p’
      In the expression:
        manipulateParams q p >>= (fmap . fmap) fromOnly . firstRow
      In an equation for ‘maybeOneOnly'’:
          maybeOneOnly' q p
            = manipulateParams q p >>= (fmap . fmap) fromOnly . firstRow
    • Relevant bindings include
        p :: params (bound at src/Fretlink/Squeal/Utils/Runners.hs:72:17)
        q :: Manipulation_ db params (Only r)
          (bound at src/Fretlink/Squeal/Utils/Runners.hs:72:15)
        maybeOneOnly' :: Manipulation_ db params (Only r)
                         -> params -> m (Maybe r)
          (bound at src/Fretlink/Squeal/Utils/Runners.hs:72:1)

Of course I can write it with less higher-level expressivity like this:

maybeOneOnly ::
  (MonadUnliftIO m, MonadPQ db m, GenericParams db params x xs, FromValue (NullPG r) r) =>
  Manipulation '[] db params (RowPG (Only r))
  -- ^ Query to run, that returns a `Only` type
  -> x
  -- ^ Query to run
  -> m (Maybe r)
  -- ^ Maybe a result in the monadic context
maybeOneOnly q p = manipulateParams q p >>= (fmap . fmap) fromOnly . firstRow

But it's not as nice ! Is there a way to write this kind of things with the handy Manipulation_ type-family or am I asking too much from the type system here ?

@adfretlink adfretlink changed the title HOF query callers in Squeal 0.6 Writing utility query callers in Squeal 0.6 Apr 4, 2020
@echatav
Copy link
Contributor

echatav commented Apr 6, 2020

There shouldn't be a need to change these functions, either their types signatures or their bodies, to accommodate Manipulation_s or Query_s. That's because a Manipulation_ calculates a Manipulation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants