如何将此C ++代码重写或转换为Haskell代码

时间:2012-01-19 04:53:37

标签: oop haskell

我想要重写或转换的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 ++中的变量)。

请帮忙。  感谢

3 个答案:

答案 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语言。