PatternSynonymsを用いて利用側コードを変更せずにある値構築子を削除する

Posted on 2017/07/27
Tags: [Haskell]

 こういう型がありましたが

data SExpr = Cons SExpr SExpr -- ^ Appending list and list
           | Nil              -- ^ A representation of empty list
           | Quote SExpr      -- ^ For lazy evaluation
           | AtomInt Int      -- ^ A pattern of the atom for @Int@ (primitive)
           | AtomSymbol Text  -- ^ A pattern of the atom for @Text@ (primitive)

(Lispの)シンボルを独立した表現として定義する必要が出てきました。 そうなるとこういうの

newtype Symbol = Symbol { unSymbol :: Text }
  deriving (IsString, Show, Eq)

を定義するのが普通だと思いますが、これだとシンボルの表現がS式としてのもの、Haskellの型としてのもの ……と、2つの表現が混在してしまいます。

-- その1
AtomSymbol Text
-- その2
newtype Symbol = Symbol { unSymbol :: Text }

解決策

 PatternSynonymsでpatternを定義してあげる。

data SExpr = Cons SExpr SExpr
           | Nil
           | Quote SExpr
           | AtomInt Int
           | AtomSymbol' Symbol -- Symbolを仲介させる
  deriving (Show, Eq)

-- シンボルを表す唯一の表現
newtype Symbol = Symbol { unSymbol :: Text }
  deriving (IsString, Show, Eq)

-- 無くなったAtomSymbolを付け足す
pattern AtomSymbol :: Text -> SExpr
pattern AtomSymbol x = AtomSymbol' (Symbol x)

 このコミット

でわかる通り、利用側コードは変更されてません 🐕
(もちろんpatternをimportする必要はある)



この記事はこちらから修正リクエストを送ることができます。
PatternSynonymsを用いて利用側コードを変更せずにある値構築子を削除する - github
ゴミ箱ボタンの左にある、鉛筆ボタンを押してね!