同じようなフィールドを持ったレコードへの変換

RecordWildCards を使って、同じようなフィールドを持つレコードを簡単に変換できる。

  • RecordA.hs
module RecordA where

data A = A { a :: Int, b :: String, c :: Int } deriving Show
  • RecordB.hs
module RecordB where

data B = B { a :: Int, b :: String, c :: Int } deriving Show
  • RecordC.hs
module RecordC where

data C = C { a :: Int, b :: String, c :: String } deriving Show
  • RecordMain.hs
{-# LANGUAGE RecordWildCards #-}
module Main where

import qualified RecordA
import qualified RecordB
import qualified RecordC

createA :: RecordA.A
createA = RecordA.A {..}
 where
  a = 1
  b = "b"
  c = 100

-- A をそのまま B に変換
toB1 :: RecordA.A -> RecordB.B
toB1 (RecordA.A {..}) = RecordB.B {..}

-- A の一部を上書きして B に変換
toB2 :: RecordA.A -> RecordB.B
toB2 (RecordA.A {..}) = RecordB.B {..}
 where
  b = "bb"

-- A を C に変換 (C.c = "aaa") (A.c は使わない)
toC1 :: RecordA.A -> RecordC.C
toC1 (RecordA.A {..}) = RecordC.C {..}
 where
  c = "aaa"

-- A を C に変換 (C.c = show A.c)
toC2 :: RecordA.A -> RecordC.C
toC2 (RecordA.A { c = ca, ..}) = RecordC.C {..}
 where
  c = show ca

main :: IO ()
main = do
  print $ createA
  print $ toB1 $ createA
  print $ toB2 $ createA
  print $ toC1 $ createA
  print $ toC2 $ createA
  • 実行
$ runhaskell RecordMain.hs
A {a = 1, b = "b", c = 100}
B {a = 1, b = "b", c = 100}
B {a = 1, b = "bb", c = 100}
C {a = 1, b = "b", c = "aaa"}
C {a = 1, b = "b", c = "100"}


DTO/Entity 変換や、DTO 同士の変換に良さげ。