Haskell Esqueleto - Maybe Keys don't bind on LeftOuterJoin

时间:2016-04-04 17:53:55

标签: haskell join yesod

I am with some trouble while making a join which uses a maybe foreign key.

My Models:

OrderItem
  productSnapshot ProductSnapshotId

ProductFlow
  productInstance ProductInstanceId
  orderItem OrderItemId Maybe

ProductSnapshot
  productInstance ProductInstanceId

ProductInstance
  code Text

And my joins:

type Entities = [(Entity OrderItem, Entity ProductSnapshot, Entity ProductInstance, Maybe (Entity ProductFlow))]

loadEntities :: OrderItemId -> Handler Entities
loadEntities oiId = runDB
  $ E.select
  $ E.from $ \(oi `E.InnerJoin` ps `E.InnerJoin` pi `E.LeftOuterJoin` pf) -> do
    E.on $ pf E.?. ProductFlowOrderItem E.==. E.just (oi ^. OrderItemId)
    E.on $ pi ^. ProductInstanceId E.==. ps ^. ProductSnapshotProductInstance
    E.on $ ps ^. ProductSnapshotId E.==. oi ^. OrderItemProductSnapshot
    E.where_ (oi ^. OrderItemId E.==. E.val oiId)
    return (oi, ps, pi, pf)

I tried the Esqueleto join showed above, but I got the following error:

Couldn't match type ‘Key OrderItem’ with ‘Maybe (Key OrderItem)’
    Expected type: EntityField OrderItem (Maybe (Key OrderItem))
      Actual type: EntityField OrderItem (Key OrderItem)
    In the second argument of ‘(^.)’, namely ‘OrderItemId’
    In the first argument of ‘E.just’, namely ‘(oi ^. OrderItemId)’

I think it is caused because I'm using a maybe foreign key. I tried other ways, and got strange type errors. I think I don't understand completely well how these joins work, so a brief explanation about E.^., E.just and E.?. would improve my Esqueleto usage.

1 个答案:

答案 0 :(得分:0)

我设法了解问题并自己解决,而不是

E.on $ pf E.?. ProductFlowOrderItem E.==. E.just (oi ^. OrderItemId)

使用此

E.on $ pf E.?. ProductFlowOrderItem E.==. (E.just . E.just) (oi ^. OrderItemId)

有必要使类型匹配,因为我们使用E.?.已经有Maybe值,因此,我们必须将右侧设为Maybe (Maybe AType),否则它会是错的,为了做到这一点,我只使用了E.just . E.just,它将包裹两次。