如何在 Esqueleto 查询中使用除非(或何时)?

How to use unless (or when) in an Esqueleto query?

我构建了一个连接几个表并进一步限制结果的查询除非一个名为IncludeAll的字段等于True.

我正在尝试这样写

fetch i = runDb . select . from $ \(a, b, c) -> do
  where_ $
        a ^. AId ==. valkey i
    &&. b ^. BField1 ==. a ^. AField2
    &&. c ^. CField1 ==. a ^. AField3
  unless (unValue $ b ^. BIncludeAll) $
    where_ $ b ^. BField2 == c ^. CField2
  return  b

但是我得到以下错误

Couldn't match expected type Bool with actual type Database.Esqueleto.Internal.Language.Value Bool in the first argument of unless

所以 unValue 不知何故并不能解决问题。实际上,b ^. BIncludeAll 之类的东西的类型是 expr (Value a).

查看源代码中的 definition of SqlExpr 也没有帮助我:

这是一个 ADT:

 data SqlExpr a where ...

PS:我使用 SQL 后端,但理想情况下这应该无关紧要,对吧?

unless 期望 Bool 作为其参数,这意味着 "Haskell world" 中的布尔值。您正在传递它 unValue $ b ^. BIncludeAll,但 b ^. BIncludeAll 不是 Value Bool 类型,它是一个 SqlExpr (Value Bool),代表 "database world" 中的布尔表达式。这是一个 SQL 语句,在评估时,returns 是一个布尔值。将 SqlExpr (Value Bool) 变成实际 Value Bool 的唯一方法是调用 select $ from $ ....

正如其他人所指出的,正确的方法是只使用 where_ (b ^. BIncludeAll ||. b ^. BField2 ==. c ^. CField2)