Search code examples
haskellalgebraic-data-types

Error when accessing specific ADT


I am defining a type and everything works fine except the method that accesses the last data constructor : JArray

I get the following error:

Not in scope: type constructor or class `JArray'
    A data constructor of that name is in scope; did you mean DataKinds?

   |
28 |     getArray::JValue->Maybe JArray
   |  

Why is this happening? I can load the module and instantiate the JArray but it won't load with the getArray method.

data JValue = JString String
            | JNumber Double
            | JBool Bool
            | JNull
            | JObject [(String, JValue)]
            | JArray [JValue]
            deriving (Eq, Ord, Show)

getString :: JValue -> Maybe String
getString (JString s) = Just s
getString _ = Nothing

getInt :: JValue -> Maybe Int
getInt (JNumber n) = Just (truncate n)
getInt _ = Nothing

getBool :: JValue -> Maybe Bool
getBool (JBool b) = Just b
getBool _ = Nothing

getObject (JObject obj) = Just obj
getObject _ = Nothing

--What is wrong in this method?

getArray :: JValue -> Maybe JArray    
getArray (JArray arr) = Just arr
getArray _ = Nothing

Solution

  • JArray is a value constructor, not a type. You cannot use JArray in type signatures.* This is actually explained in the error: Not in scope: type constructor or class `JArray'.

    Since we see this:

    data JValue = JString String
                | JNumber Double
                | JBool Bool
                | JNull
                | JObject [(String,JValue)]
                | JArray [JValue]           -- This line defines JArray
    

    So JArray :: [JValue] -> JValue. Looking at your function, but ignoring the erroneous type signature:

    getArray (JArray arr) = Just arr
    -- ^ arr :: [JValue], so Just arr :: Maybe [JValue]
    getArray _ = Nothing
    -- ^ Nothing :: Maybe a
    

    So, since you're pattern matching on some JValue, the function has type getArray :: JValue -> Maybe [JValue]. This is because types and inhabitants of that type are distinct.


    * except with DataKinds, but this is a separate concern.