leftJoinF in Opaleye and IfPP

53 views Asked by At

I want to use a LEFT JOIN to fetch products and their (optional) attributes. I have types like:

type ProductPGR = ProductPoly (Column (PGID Product)) (Column PGText)
type ProductAttributePGR = ProductAttributePoly (Column (PGID ProductAttribute)) (Column (PGID Product)) (Column PGInt4)

My intention was to use:

  (p :: ProductPGR, pa :: Maybe ProductAttributePGR) <- leftJoinF
    (\p' pa' -> (p', Just pa'))
    (\p'     -> (p', Nothing))
    (\p' pa' -> productId p' .== paProductId pa')
    productQuery
    productAttributeQuery -< ()

This doesn't compile because:

No instance for (Default
                     IfPP
                     (Maybe
                        (ProductAttributePoly
                           (Column (PGID ProductAttribute))
                           (Column (PGID Product))
                           (Column PGInt4))))
                     (Maybe
                        (ProductAttributePoly
                           (Column (PGID ProductAttribute))
                           (Column (PGID Product))
                           (Column PGInt4))))
arising from a use of ‘leftJoinF’

Am I really supposed to define this instance? What is it for and how would I do that?

Or if I'm not supposed to use Maybe, what else would I do?

1

There are 1 answers

0
Tom Ellis On BEST ANSWER

You can't return a Maybe out of a functional join. Functional join allows you to avoid Nullable in the sense that it hides the IS NULL check from you. It doesn't allow you to "lift the nullability" onto the Haskell side.