使用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
相关产品推荐
相关产品推荐

