Haskell でオブジェクト指向 (1')

先ほど書いたコードを少しだけ修正。
あと、モナドを使ってやりたいことを書いておく。

まず、Person 型の setXXX の実装を少し変更。ラベルを使って簡単に書ける。

setName :: String -> Person -> Person
setName newName x = x { name = newName }

setAge :: Int -> Person -> Person
setAge newAge x = x { age = newAge }

次に、せっかく Entity に ID をつけたので、Eq を実装してみた。ID のラベルが id だと、Prelude の関数とバッティングするので、eid に変更した。

data Entity a =
  Entity {
    eid     :: Integer,
    version :: Integer,
    state   :: a
  }
  deriving Show

instance Eq (Entity a)
  where
    x == y = eid x == eid y

最後に、モナドを使ってやりたいこと。
流れるようなインタフェースとか...

main =
  let
    g0 = IdGen 1000
    (x, g1) = g0
      >>= makeEntity (Person "Foo", 12)
      >>= fmap (setName "Bar")
      >>= fmap (setAge 23)
    (y, g2) = g1
      >>= makeEntity (Person "Hoge", 34)
      >>= updateEntity (Person "Fuga", 45)
  in do
    print g0
    print g1
    print x
    print g2
    print y

もっと、手続きっぽくこんな感じとか...

main =
  do
    g0 <- IdGen 1000
    print g0
    (x1, g1) <- g0 >>= makeEntity (Person "Foo", 12)
    print g1
    print x1
    x2 <- x1 >>= fmap (setName "Bar")
    print x2
    x3 <- x2 >>= fmap (setAge 23)
    print x3
    (y1, g2) <- g1 >>= makeEntity (Person "Hoge", 34)
    print g2
    print y1
    y2 <- y1 >>= updateEntity (Person "Fuga", 45)
    print y2

少し自分でやってみたけれど、なかなか思うようにいかない。(;_;)