Using Servant.Elm and Elm.Derive with Int64 (deriving and generating definition for an unboxed type) causes an Elm syntax error

Viewed 87

I'm trying to use Servant.Elm and Elm.Derive to generate an Elm Api from a Haskell Servant Api including Int64 which I learnt is defined as a primitive unboxed Haskell type:

data {-# CTYPE "HsInt64" #-} Int64 = I64# Int#

In the generated Elm module the Haskell type Int64 is represented by the following Elm type:

type Int64  =
    I64# Int#

, which is not valid Elm syntax:

-- UNEXPECTED SYMBOL  /Users/XXX/elm-frontend/src/Derived.elm

I got stuck on this symbol:

14|     I64# Int#
           ^
It is not used for anything in Elm syntax. Try removing it?

I cannot find an easy way to configure this with the ElmOptions. Is this a bug or a missing feature in the Servant.Elm package? Or, are there other reasons why I should stay away from Int64 in my Servant API?

Even if I could rewrite my Servant Api to use something else than Int64 or manually write Elm code for everything related to routes using Int64 I would like to know if there is a way to derive/generate a valid Elm definition for Int64 or other Haskell types with # as constructor suffix and/or type suffix.

An attempt at a minimal test case:

{-# LANGUAGE TemplateHaskell   #-}

module DeriveElmTest where

import Data.Proxy
import Servant.API (EmptyAPI)
import Data.Int (Int64)
 
import Elm.Derive (
   defaultOptions
 , deriveElmDef
 )

import Servant.Elm (
   DefineElm (DefineElm)
 , Proxy (Proxy)
 , defElmImports
 , defElmOptions
 , generateElmModuleWith
 )
 
deriveElmDef defaultOptions ''Int64
  
main :: IO ()
main =
  generateElmModuleWith
    defElmOptions
    [ "Derived"]
    defElmImports
    "elm-frontend/src"
    [ DefineElm (Proxy :: Proxy Int64)]
    (Proxy :: Proxy EmptyAPI)

, which produces the following Elm module:

module Derived exposing(..)

import Json.Decode
import Json.Encode exposing (Value)
-- The following module comes from bartavelle/json-helpers
import Json.Helpers exposing (..)
import Dict exposing (Dict)
import Set
import Http
import String
import Url.Builder

type Int64  =
    I64# Int#

jsonDecInt64 : Json.Decode.Decoder ( Int64 )
jsonDecInt64 =
    Json.Decode.lazy (\_ -> Json.Decode.map I64# (jsonDecInt#))


jsonEncInt64 : Int64 -> Value
jsonEncInt64 (I64# v1) =
    jsonEncInt# v1
0 Answers
Related