Haskell使用forEach渲染HTML节点时遇类型匹配错误
类型错误:无法匹配
Text与Data.MonoTraversable.Element mono0 错误信息
Web/View/HardwareVendors/Show.hs:7:33 • Couldn't match expected type ‘Text’ with actual type ‘Data.MonoTraversable.Element mono0’ The type variable ‘mono0’ is ambiguous • In the second argument of ‘forEach’, namely ‘renderInput’ In the first argument of ‘toHtml’, namely ‘((forEach hardwareVendor.required_fields) renderInput)’ In the expression: toHtml ((forEach hardwareVendor.required_fields) renderInput) | 7 | html ShowView { .. } = [hsx| | ^...
相关源码
module Web.View.HardwareVendors.Show where import Web.View.Prelude data ShowView = ShowView { hardwareVendor :: HardwareVendor } instance View ShowView where html ShowView { .. } = [hsx| {breadcrumb} <h1>{hardwareVendor.name}</h1> <form action="{hardwareVendor.getUrl}" method="get"> -- required_fields is a Text[] postgres column {forEach hardwareVendor.required_fields renderInput} <input type="submit" value="Submit"> </form> |] where breadcrumb = renderBreadcrumb [ breadcrumbLink "HardwareVendors" HardwareVendorsAction , breadcrumbText "Show HardwareVendor" ] renderInput :: Text -> Html renderInput field = [hsx| <label for="{field}">{field}</label> <input type="text" id="{field}" name="{field}" required> <br> |]
其中required_fields是Postgres的Text[]类型列,renderInput接受Text参数并返回Html,使用forEach遍历该字段时触发上述类型错误。
解决方法
问题根源是IHP中PostgreSQL的数组类型会映射为Array Text(来自Database.PostgreSQL.Simple.Array),而非Haskell原生的[Text]列表,导致forEach无法自动推断元素类型。
方法1:转换为原生列表
导入Database.PostgreSQL.Simple.Array模块(如果尚未导入),然后用toList将Array Text转为普通列表:
{forEach (toList hardwareVendor.required_fields) renderInput}
方法2:显式指定类型
给forEach添加类型注解,明确元素类型为Text:
{forEach @Text hardwareVendor.required_fields renderInput}
内容的提问来源于stack exchange,提问作者Geoff Langenderfer
相关产品推荐
相关产品推荐

