Haskell 类似于 OCaml 中的私人记录

Haskell private records like in OCaml

在 OCaml 模块签名中我可以这样写:

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

(注意private的用法。)

这允许导入我的模块的代码与 monotype_description 等字段进行模式匹配,但不允许导入我的模块的代码构造记录。

我可以在Haskell中编写具有类似访问权限的代码吗?我想在不允许记录构造的情况下针对 monotypeDescription 字段进行模式匹配。

我知道存在 PatternSynonyms 语言扩展,但我不知道如何使用它。如果可用的话,我也更喜欢更简单的解决方案。

在您的模块中:

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"

在其他地方,进行模式匹配:

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

现在 f j 将是 "5"f n 将是 "nope"

或者,使用 ViewPatterns 扩展名:

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

如果至少还允许记录更新(您可以导入或不导入该字段),则无法匹配字段。我认为限制更多是因为没有明显的语法来仅导入访问器...

真正的解决办法是使用PatternSynonyms。您需要单向模式:

{-# 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

现在,您可以匹配 Monotype { monotype_free_variables, monotype_description } 但不能构造它:

λ> 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 ""