Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell private records like in OCaml

Tags:

haskell

record

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.

like image 360
Calebmer Avatar asked Jan 01 '23 08:01

Calebmer


1 Answers

You can't match against the fields without also allowing at least record update (you either import the field or not). I think the restriction is more because there isn't an obvious syntax for importing only accessors...

The proper solution is really to use PatternSynonyms. You'll want a uni-directional pattern:

{-# LANGUAGE PatternSynonyms #-}
module MyModule ( Monotype(Monotype) ) where

import Data.Set

data Monotype = MT (Set String) String

pattern Monotype :: Set String -> String -> Monotype
pattern Monotype { monotype_free_variables, monotype_description }
  <- MT monotype_free_variables monotype_description

Now, you can match against Monotype { monotype_free_variables, monotype_description } but you can't construct it:

λ> Monotype { monotype_free_variables = f1, monotype_description = f2 } = m1
λ> Monotype f1 f2 = m1
λ> m3 = Monotype { monotype_free_variables = mempty, monotype_description = "" }
<interactive>:3:6: error:
    • non-bidirectional pattern synonym ‘Monotype’ used in an expression
    • In the expression:
        Monotype
          {monotype_free_variables = mempty, monotype_description = ""}
      In an equation for ‘m3’:
          m3
            = Monotype
                {monotype_free_variables = mempty, monotype_description = ""}
λ> m3 = Monotype mempty ""

<interactive>:4:6: error:
    • non-bidirectional pattern synonym ‘Monotype’ used in an expression
    • In the expression: Monotype mempty ""
      In an equation for ‘m3’: m3 = Monotype mempty ""
like image 109
Alec Avatar answered Jan 08 '23 20:01

Alec