我想要重写或转换的c ++代码是:
class numberClass
{
private:
int value;
public:
int read()
{
return value;
}
void load(int x)
{
value = x;
}
void increment()
{
value= value +1;
}
};
int main()
{
numberClass num;
num.load(5);
int x=num.read();
cout<<x<<endl;
num.increment();
x=num.read();
cout<<x;
}
我不知道如何在haskell中创建任何可以在整个程序中保持价值的实体(如C ++中的变量)。
请帮忙。 感谢
答案 0 :(得分:10)
基本上,你不能。值是不可变的,Haskell在存储值的方框中没有变量,比如C ++和类似的。 可以使用IORef
(可以存储值的框)来执行类似操作,但使用它们几乎总是错误的设计。
Haskell是一种非常不同的编程语言,尝试将代码从C,C ++,Java等语言转换为Haskell并不是一个好主意。人们必须从不同角度看待任务,并以不同的方式处理它。
话虽如此:
module Main (main) where
import Data.IORef
main :: IO ()
main = do
num <- newIORef 5 :: IO (IORef Int)
x <- readIORef num
print x
modifyIORef num (+1)
x <- readIORef num
print x
答案 1 :(得分:8)
好吧,假设它是包装,而不是可变性,你可以轻松地拥有一个只允许构造常量值和增量的类型:
module Incr (Incr, incr, fromIncr, toIncr) where
newtype Incr a = Incr a deriving (Read, Show)
fromIncr :: Incr a -> a
fromIncr (Incr x) = x
incr :: (Enum a) => Incr a -> Incr a
incr (Incr x) = Incr (succ x)
toIncr :: a -> Incr a
toIncr = Incr
正如Daniel指出的那样,可变性是不可能的,但是你的类的另一个目的是封装,这个模块就像C ++类一样提供。当然对于Haskell程序员来说,这个模块可能看起来不太有用,但也许你有一些用例,你想静态地阻止库用户使用常规的加法或乘法。
答案 2 :(得分:2)
将代码直接翻译为haskell是相当愚蠢的,但当然可能(如Daniel的回答所示)。
通常,当您在haskell中使用state时,您可以使用State Monad
。只要您在State Monad中执行,您就可以查询和更新您的状态。如果您希望能够再添加一些IO(如示例所示),则需要将State Monad堆叠在IO之上。
使用这种方法,您的代码可能如下所示:
import Control.Monad.State
import Prelude hiding(read)
increment = modify (+1)
load = put
read = get
normal :: StateT Int IO ()
normal = do
load 5
x <- read
lift (print x)
increment
x <- read
lift (print x)
main = evalStateT normal 0
但是这里你的numberClass没有明确的类型。如果你想要这个,你可以使用一个很好的hackage库:data-lenses 使用镜头代码可能更接近您的C ++版本:
{-# LANGUAGE TemplateHaskell #-}
import Control.Monad.State(StateT,evalStateT,lift)
import Prelude hiding(read)
import Data.Lens.Lazy((~=),access,(%=))
import Data.Lens.Template(makeLenses)
data Number = Number {
_value :: Int
} deriving (Show)
$( makeLenses [''Number] )
increment = value %= succ
load x = value ~= x
read = access value
withLens :: StateT Number IO ()
withLens = do
load 5
x <- read
lift $ print x
increment
x <- read
lift $ print x
main = evalStateT withLens (Number 0)
仍然不完全是你的代码...但是,它是haskell而不是另一种OO语言。