Частные записи на Haskell как в OCaml - PullRequest
0 голосов
/ 29 января 2019

В сигнатуре модуля OCaml я могу написать:

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

(обратите внимание на использование private.)

Это позволяет коду, импортирующему мой модуль, сопоставлять шаблоны с такими полями, какmonotype_description но не позволит импортировать код моего модуля для создания записи.

Могу ли я написать код с аналогичным разрешением доступа в Haskell?Я хотел бы сопоставить шаблон с полем monotypeDescription, не допуская построения записи.

Я знаю, что существует расширение языка PatternSynonyms, но я не знаю, как его использовать.Я также предпочел бы более простое решение, если оно доступно.

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Нельзя сопоставлять поля, не разрешив хотя бы обновление записи (вы либо импортируете поле, либо нет).Я думаю, что ограничение больше, потому что нет очевидного синтаксиса для импорта только методов доступа ...

Надлежащее решение - использовать 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 ""
0 голосов
/ 29 января 2019

В вашем модуле:

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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...