我正在写一些CRUD助手以获得乐趣和利润,而我发现自己需要空路或无路线。 mempty
到:>
,如果愿意的话。
这是我想写的:
type Index model =
Reassoc (QueryParams model :> Get '[JSON] (Collection model))
type family Reassoc xs where
Reassoc ((x :> y) :> z) = Reassoc (x :> Reassoc (y :> z))
Reassoc (x :> y) = x :> y
type family QueryParams model
type instance QueryParams User =
MakeQueryParams '[ '("organizationId", Int) ]
这一切都归功于这个人:
type family MakeQueryParams xs where
MakeQueryParams ( '(sym, ty) ': xs )
= QueryParam sym ty :> MakeQueryParams xs
MakeQueryParams '[]
= ... :(
到目前为止,我已经通过在这些系列中使用next
参数解决了这个问题,但对于Servant而言,它的惯用性要少得多。
type family MakeQueryParams xs next where
MakeQueryParams '[] next =
next
MakeQueryParams ('(sym, ty) ': xs) next =
QueryParam sym ty :> MakeQueryParams xs next
type Index model = QueryParams model (Get '[JSON] (Collection model))
type family QueryParams model next
type instance QueryParams User next =
MakeQueryParams '[ '("organizationId", Int) ] next
答案 0 :(得分:0)
如果您真的坚持写作
type API = QueryParams '[ '("id", Int) ] :> Get '[JSON] Bool
您将foldr
这样的想法/解决方案(完全可以)与新的组合器相结合:
data QueryParams (ps :: [(Symbol, *)])
instance HasServer api ctx
=> HasServer (QueryParams '[] :> api) ctx where
type ServerT (QueryParams '[] api) m = ServerT api m
route = ...
instance HasServer (QueryParam sym ty :> MakeQueryParams ('(sym, ty) ': ps) api) ctx
=> HasServer (QueryParams ('(sym, ty) ': ps) api) ctx where
type ServerT (QueryParams ('(sym, ty) ': ps) api) m = ...
route = ...
为nil和cons案例编写单独的实例将使实例的实现更加直接。
可以认为我们必须引入新的组合器,否则我们将无法在正确的位置插入类型族。有点像我们有时需要编写newtype
来编写不同的实例。