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

使用Servant.Elm与Elm.Derive处理Int64时生成无效Elm语法的报错问题

问题原因

你遇到的报错是elm-bridge默认转换逻辑未处理GHC未装箱类型的特殊标识符导致的:GHC内部的未装箱类型、构造器后缀的#属于Haskell合法标识符,但在Elm中属于非法字符,而elm-bridge默认会原封不动迁移Haskell的类型名、构造器名,没有对这类内置原生类型做特殊映射,属于包的缺失特性,不属于逻辑bug。

是否要在Servant API中避免使用Int64

如果没有强制的64位整数精度要求,优先用Haskell原生Int类型即可,默认会被映射为Elm原生Int,不会出现转换问题。如果确实需要保证64位数值精度,也不需要刻意避开,可通过配置解决转换问题。

带#后缀的Haskell类型的合法Elm代码生成方法

方法1:修改转换配置过滤非法字符

通过Options的名字修饰符字段,全局过滤掉标识符中的#,或针对特定类型做名字替换,示例配置如下:

import Elm.Derive (Options(..), defaultOptions)

customElmOptions :: Options
customElmOptions = defaultOptions
  { -- 替换类型名中的#
    typeNameModifier = \tName -> case tName of
      "Int#" -> "Int"
      _ -> filter (/= '#') tName
    -- 替换构造器名中的#
  , constructorNameModifier = \cName -> case cName of
      "I64#" -> "I64"
      _ -> filter (/= '#') cName
  }

之后使用customElmOptions替代defaultOptions调用deriveElmDef即可,生成的构造器和类型名会自动去掉#,符合Elm语法规范。

方法2:手动注册类型映射(更推荐,性能更好)

如果不需要在Elm侧保留Int64的自定义包装类型,可手动给Int64编写ElmType实例,直接映射为Elm原生Int类型,完全避免生成带非法字符的自定义定义:

import Elm.Class (ElmType(..))
import Elm.TyRep (ETyp(..), ETCon(..))

instance ElmType Int64 where
  elmType = ECon $ ETCon "Int"
  toElmTypeDef _ = []

这种方式生成的代码会直接使用Elm内置的Int编解码逻辑,不会生成冗余的自定义Int64类型,也不会出现非法标识符问题。如果担心Elm Int的精度不足以覆盖64位整数范围,也可以映射为Elm的String类型,配合对应的编解码逻辑即可。

所有带#后缀的GHC未装箱类型都可以通过上述两种方式处理,完成合法Elm代码的生成。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:24:01