C++ 第二部分,因为它更准确地表达了我想强调的原始代码的意图。然而,考虑因素在很大程度上是正交的,我的对象建模方法可以很容易地与@Rotsor演示的基于状态的易变性建模方法相结合。另外,请记住,两者都非常糟糕,在实践中,您永远不会希望以这种方式编写Haskell
C++ 第二部分,因为它更准确地表达了我想强调的原始代码的意图。然而,考虑因素在很大程度上是正交的,我的对象建模方法可以很容易地与@Rotsor演示的基于状态的易变性建模方法相结合。另外,请记住,两者都非常糟糕,在实践中,您永远不会希望以这种方式编写Haskell,c++,haskell,monads,C++,Haskell,Monads,第二部分,因为它更准确地表达了我想强调的原始代码的意图。然而,考虑因素在很大程度上是正交的,我的对象建模方法可以很容易地与@Rotsor演示的基于状态的易变性建模方法相结合。另外,请记住,两者都非常糟糕,在实践中,您永远不会希望以这种方式编写Haskell。同样,你也不想像原始一样写C++。应该注意的是,(a)= a- > ->布尔-< /代码>可以被改变为(A1,A2)= > A1-> A2-> BOOL 避免这个问题,或者说为什么这是不可能的。@ RoSoo:不幸的是,这仅仅是在简单的情况下
第二部分,因为它更准确地表达了我想强调的原始代码的意图。然而,考虑因素在很大程度上是正交的,我的对象建模方法可以很容易地与@Rotsor演示的基于
状态的易变性建模方法相结合。另外,请记住,两者都非常糟糕,在实践中,您永远不会希望以这种方式编写Haskell。同样,你也不想像原始一样写C++。应该注意的是,<代码>(a)= a- > ->布尔-< /代码>可以被改变为<代码>(A1,A2)= > A1-> A2-> BOOL 避免这个问题,或者说为什么这是不可能的。@ RoSoo:不幸的是,这仅仅是在简单的情况下避免了问题。我可能应该选择一个更好的例子。一个高阶的“合并排序列表”函数怎么样?它接受一个比较函数,两个排序的项目列表,并返回合并和排序的列表?@camcann,啊,这很有意义!非常感谢。
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();
}
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)
*** Type : StateT FieldsA IO ()
*** Does not match : StateT FieldsA (StateT FieldsB IO) ()
data MainState = MainState { objA :: FieldsA, objB :: FieldsB }
type Main t = StateT MainState IO t
withObjA :: StateT FieldsA IO t -> Main t
withObjB :: StateT FieldsB IO t -> Main t
test :: Main ()
test = do
withObjA $ do
setX_A 2
printX_A
withObjB $ do
printX_A
setX_B 5
printX_B
withPart :: Monad m => (whole -> part) -> (part -> whole -> whole) -> StateT part m t -> StateT whole m t
withPart getPart setPart action = do
whole <- get
(t, newPart) <- lift $ runStateT action (getPart whole)
put (setPart newPart whole)
return t
withObjA :: StateT FieldsA IO t -> Main t
withObjA = withPart objA (\objA mainState -> mainState { objA = objA })
withObjB :: StateT FieldsB IO t -> Main t
withObjB = withPart objB (\objB mainState -> mainState { objB = objB })
data FieldsA = FieldsA { x_A :: IORef Int}
constA :: Int -> IO FieldsA
constA x = do xRef <- newIORef x
return $ FieldsA xRef
class A a where
getX_A :: a -> IO Int
setX_A :: a -> Int -> IO ()
printX_A :: a -> IO ()
instance A FieldsA where
getX_A = readIORef . x_A
setX_A = writeIORef . x_A
printX_A a = getX_A a >>= print
data A = A { _getX_A :: IO Int
, _setX_A :: Int -> IO ()
, _printX_A :: IO ()
}
data B = B { _parent_B :: A
, _getX_B :: IO Int
, _setX_B :: Int -> IO ()
, _printX_B :: IO ()
}
class CastA a where castA :: a -> A
class CastB b where castB :: b -> B
instance CastA A where castA = id
instance CastA B where castA = _parent_B
instance CastB B where castB = id
getX_A x = _getX_A $ castA x
setX_A x = _setX_A $ castA x
printX_A x = _printX_A $ castA x
getX_B x = _getX_B $ castB x
setX_B x = _setX_B $ castB x
printX_B x = _printX_B $ castB x
newA x = do xRef <- newIORef x
return $ A { _getX_A = readIORef xRef
, _setX_A = writeIORef xRef
, _printX_A = readIORef xRef >>= print
}
newB xA xB = do xRef <- newIORef xB
parent <- newA xA
return $ B { _parent_B = parent
, _getX_B = readIORef xRef
, _setX_B = writeIORef xRef
, _printX_B = readIORef xRef >>= print
}
test :: IO ()
test = do a <- newA 1
b <- newB 2 3
printX_A a
printX_A b
setX_A a 4
printX_A a
printX_B b