Мне нужно преобразовать этот код на С++
class A {
public: 
   int x_A;
    void setX_A (int newx) {
        x_A = newx;
    }
    void printX_A() {
       printf("x_A is %d", x_A);
    }
};
class B : public A {
public:
    int x_B;
    void setX_B (int newx) {
       x_B = newx;
    }
    void printX_B() {
       printf("x_B is %d", x_B);
    }
};
main() {
    A objA;
    B objB;
    objA.setX_A(2);
    objA.printX_A();
    objB.printX_A();
    objB.setX_B(5);
    objB.printX_B();
}
в код Haskell и имитировать main() с помощью State (или StateT) Monad.
Что я сделал до сих пор:
import Control.Monad.State
import Control.Monad.Identity
-- Fields For A
data FieldsA = FieldsA {x_A::Int} deriving (Show)
    -- A Class Constructor
constA :: Int -> FieldsA
constA = FieldsA
class A a where
    getX_A :: StateT a IO Int
    setX_A :: Int -> StateT a IO ()
    printX_A :: StateT a IO ()
instance A FieldsA where
    getX_A = get >>= return . x_A
    setX_A newx = do
        fa <- get
        put (fa { x_A = newx })
    printX_A = do
        fa <- get
        liftIO $ print fa
        return ()
data FieldsB = FieldsB{ fa::FieldsA, x_B::Int } deriving (Show)
constB :: Int -> Int -> FieldsB
constB int1 int2 = FieldsB {fa = constA int1, x_B = int2}
class A b => B b where
    getX_B :: StateT b IO Int
    setX_B :: Int -> StateT b IO ()
    printX_B :: StateT b IO ()
-- A Functions for Class B
instance A FieldsB where
    getX_A = do
      (FieldsB (FieldsA x_A) x_B) <- get
      return (x_A)
    setX_A newx = do
        (FieldsB (FieldsA x_A) x_B) <- get
        put (constB newx x_B)
    printX_A = do
        fb <- get
        liftIO $ print fb
        return ()
-- B specific Functions
instance B FieldsB where
    getX_B = get >>= return . x_B
    setX_B newx = do
        fb <- get
        put (fb { x_B = newx })
    printX_B = do
        fb <- get
        liftIO $ print fb
        return ()
test :: StateT FieldsA (StateT FieldsB IO ) ()
test = do
      x <- get
      setX_A 4
      printX_A
      --lift $ setX_A 99
      --lift $ setX_B 99
      --lift $ printX_A
      --lift $ printX_B
      --printX_A
      return ()
go = evalStateT (evalStateT test (constA 1)) (constB 2 3)
--go = runIdentity $ evalStateT (evalStateT test (constA 1)) (constA 1)
test main().
Теперь о проблеме у меня: Когда я использую лифт, он работает нормально, потому что функция становится типа StateT FieldsB, но когда я пытаюсь использовать setX_A без подъема, возникает проблема
*** Type           : StateT FieldsA IO ()
*** Does not match : StateT FieldsA (StateT FieldsB IO) ()
Если я изменил тип setX_A на второй, то он не будет работать, когда я буду использовать его с лифтом (потому что класс B получен из A).
