invisible / hidden field in the constructor
Asked Answered
G

1

12

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.

Gypsophila answered 23/7, 2012 at 6:43 Comment(0)
G
11

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.

Grefer answered 23/7, 2012 at 6:59 Comment(4)
"It is not possible to export some fields of a given constructor and not other fields of the same constructor, however." Yes, it is. module MyModule (DT(C1, int)) only exports int, but not str. Also note that your DT(C1) does not export any of the fields, so int and str are invisible in your code sample.Comparable
@Comparable I did not know that! I will correct my answer, thank you.Khachaturian
"only visible as a function, not as a field" — not true either. You can use it to update the record.Ruscher
No, it's not corrected. The way you export it doesn't matter. What you're trying to achieve ("only visible as a function, not as a field") is simply not possible. For that, you have to define it as a function, not as a field.Ruscher

© 2022 - 2024 — McMap. All rights reserved.