haskelltypesderived-typesderived-instances

invisible / hidden field in the constructor


I am ploughing through Learn You a Haskell for Great Good, and I have reached up to section 8.4, "Derived Instances". In this section, there's the following data type declaration:

data Person = Person { firstName :: String  
                     , lastName :: String  
                     , age :: Int  
                     } deriving (Eq)

While trying

*Main> mikeD == Person {firstName = "Michael", lastname = "Diamond", age = 43}

I got the following error:

<interactive>:55:41:
`lastname' is not a (visible) field of constructor `Person'

By correcting lastname to lastName I removed the error.

Question:

In the error message the word (visible) hints to me that there must be the possibility of declaring a field as hidden / invisible. Is this correct or not? If it is, how can I declare a field in the constructor as hidden, and what are the general scenarios where one would need to declare hidden fields? If you could explain this by giving a simple example of their use, that would be appreciated.

Note: I could not find any reference to/details about hidden or invisible field in LYAH.


Solution

  • It is possible to hide a field of a record, or a constructor of any data type, although not at the declaration site. The idea is to simply choose not to export that constructor and/or field from the module, like so:

    module MyModule (DT(C1, int, mStr)) where
    
    data DT = C1 -- visible
                 { 
                   int :: Int, -- visible
                   str :: String -- hidden
                 }
            | C2 -- hidden
                 {
                   dbl :: Double, -- hidden
                   mStr :: Maybe String -- visible
                 }
    

    Note that everything inside MyModule still has access to both constructors and all four fields, but in some other module that imports MyModule only the exported ones are visible.