Trying to do the JSON de-serialisation for a data type with TypeLits, I get stuck with the following problem:
Couldn't match type ‘n’ with ‘2’ ‘n’ is a rigid type variable bound by the instance declaration at test.hs:14:10 Expected type: aeson-0.11.2.1:Data.Aeson.Types.Internal.Parser (X n) Actual type: aeson-0.11.2.1:Data.Aeson.Types.Internal.Parser (X 2)
How would be the correct syntax to allow Nat generically in the FromJSON instance in the following example:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
import GHC.TypeLits
import Data.Aeson
import Control.Monad (mzero)
data X (n :: Nat) where
A :: Integer -> X 1
B :: Integer -> X 2
instance FromJSON (X n) where
parseJSON (Object o) = do
v <- o .: "val"
t <- o .: "type"
case t of
"a" -> return $ A v
"b" -> return $ B v
parseJSON _ = mzero
Since you obviously cannot know the type you are going to deserialize at compile time, the exact type needs to be hidden in an existential and then restored via pattern matching. I usually use a generic
Some
type to hide phantom types.Now you can write the instance as
However, you also need to enable the
FlexibleInstances
extension.