You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Barbies库处理高种类数据类型的FromForm实例推导问题

解决Barbie类型的FromForm无重复实现问题

问题背景

我们有一个基于Barbies库定义的泛型数据类型:

data FormInputH f = FormInputH
  { formNameH :: f Text,
    formEmailH :: f Text,
    formAgeH :: f Int
  }
  deriving stock (Generic)
  deriving anyclass (ApplicativeB, ConstraintsB, FunctorB, TraversableB)

想要为它实现http-api-data库的FromForm实例,手动编写的无重复版本尝试使用预定义字段名和btraverse,但编译失败:

预定义字段名:

formFieldNames :: FormInputH (Const Text)
formFieldNames =
  FormInputH
    (Const "name")
    (Const "email")
    (Const "age")

失败的实例代码:

instance (Applicative f) => FromForm (FormInputH f) where
  fromForm f = btraverse (\(Const name) -> pure <$> parseUnique name f) formFieldNames

编译错误:

• Could not deduce (FromHttpApiData a)
    arising from a use of ‘parseUnique’
  from the context: Applicative f
    bound by the instance declaration at src/FormInput.hs:41:10-51
  Possible fix:
    add (FromHttpApiData a) to the context of
      a type expected by the context:
        forall a. Const Text a -> Either Text (f a)

错误原因

btraverse要求遍历函数对**所有类型a**都能生效,但parseUnique需要FromHttpApiData a的约束。虽然我们知道FormInputH的字段类型(Text、Int)都满足该约束,但编译器无法自动推导这一点——它看不到a的具体类型,无法确认约束成立。

解决方案

利用Barbies库的ConstraintsB提供的btraverseWithConstraint函数,结合AllBF约束来传递类型约束:

import Data.Constraint (Dict(..))
import Barbies.Constraints (AllBF, btraverseWithConstraint)

instance (Applicative f, AllBF FromHttpApiData FormInputH) => FromForm (FormInputH f) where
  fromForm form = btraverseWithConstraint @FromHttpApiData
    (\Dict (Const name) -> pure <$> parseUnique name form)
    formFieldNames

代码解释

  1. AllBF FromHttpApiData FormInputH约束:明确告诉编译器,FormInputH的所有字段类型(Text、Int)都实现了FromHttpApiData类型类。
  2. btraverseWithConstraint函数:这是ConstraintsB提供的遍历函数,它能在遍历每个字段时,自动获取对应类型的约束字典(Dict FromHttpApiData a),证明当前字段的类型满足FromHttpApiData约束。
  3. 遍历函数:我们忽略Dict(因为约束已经保证它存在),用预定义的字段名调用parseUnique,再通过pure把解析结果包装成f a类型,最终组合成FormInputH f实例。

这个实现和手动编写的版本完全等效,同时消除了代码重复。


内容的提问来源于stack exchange,提问作者l7r7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:19:52