Search code examples
haskellrecord

Haskell private records like in OCaml


In an OCaml module signature I can write:

type monotype = private {
  monotype_free_variables: StringSet.t Lazy.t;
  monotype_description: monotype_description;
}

(Note the use of private.)

This allows the code importing my module to pattern match against fields like monotype_description but will not allow code importing my module to construct the record.

Can I write code with similar access permission in Haskell? I’d like to pattern match against a monotypeDescription field without allowing record construction.

I’m aware that a PatternSynonyms language extension exists, but I don’t know how to use it. I’d also prefer a simpler solution if available.


Solution

  • In your module:

    module MyMod (MyType(), myGetter, j, n) where -- the key is that MyData is not exported
    
    data MyType = MyData (Maybe Int) String
    
    myGetter (MyData x _) = x
    
    j = MyData (Just 5) "abc"
    
    n = MyData Nothing "abc"
    

    Elsewhere, to do the pattern matching:

    f x | Just i <- myGetter x = show i
        | otherwise            = "nope"
    

    Now f j will be "5" and f n will be "nope".

    Alternatively, with the ViewPatterns extension:

    {-# LANGUAGE ViewPatterns #-}
    f (myGetter -> Just i) = show i
    f _                    = "nope"