如何將這部分C代碼翻譯成Haskell?據我所知,我必須使用國家monad,但我不知道如何。將C代碼翻譯成Haskell
int x = 1;
int y = 2;
x = x * y;
y = y + x;
如何將這部分C代碼翻譯成Haskell?據我所知,我必須使用國家monad,但我不知道如何。將C代碼翻譯成Haskell
int x = 1;
int y = 2;
x = x * y;
y = y + x;
字面翻譯就是使用IORefs:
import Data.IORef
main :: IO()
main = do x <- newIORef 1
y <- newIORef 2
y_val <- readIORef y
modifyIORef x (\v -> v * y_val)
x_val <- readIORef x
modifyIORef y (\v -> v + x_val)
正如你所看到的,命令式編程是在Haskell難看。這是故意的,哄你使用功能風格。您可以定義一些輔助功能,雖然,使這個更愜意:
import Data.IORef
-- x := f x y
combineToR :: (a -> t -> a) -> IORef a -> IORef t -> IO()
combineToR f x y = do y_val <- readIORef y
modifyIORef x (\v -> f v y_val)
addTo :: Num a => IORef a -> IORef a -> IO()
addTo = combineToR (+)
multWith :: Num a => IORef a -> IORef a -> IO()
multWith = combineToR (*)
main :: IO()
main = do x <- newIORef 1
y <- newIORef 2
multWith x y
addTo y x
您的初始'main',應該是'y_val < - readIORef x' - 就像現在一樣,它會放出'x'。 – rampion 2011-06-01 17:41:36
@rampion謝謝,修復 – 2011-06-01 20:27:28
函數式語言的重點在於您不這樣做,創造新的價值或使用遞歸。
如果你喜歡只打印這些值,
x = 1
y = 2
a = x*y
b = y+x
main = do
putStrLn ("x*y: " ++ a)
putStrLn ("y+x: " ++ b)
如果這是家庭作業,請其標記爲如此,我會改變我的答案。
這確實是一項家庭作業。其中的一部分,更加精確。我必須在Haskell中翻譯一個用C語言實現的電話簿。我只想看看如何執行set/get操作。 – 2011-05-31 19:26:16
@Bigba Mbum你可能不需要它們。在Haskell中,很少使用set和get操作。大多數可以用純粹的方式來定義。 – fuz 2011-05-31 19:30:18
get和set是非常必要的,除非你的老師知道你住在哪裏,喝過量的伏特加和看恐怖片,否則我不會使用它。 – 2011-06-01 04:04:44
假設,你有兩個整數作爲國家:
f = do put (1,2)
modify (\(x,y) -> (x*y,y))
modify (\(x,y) -> (x,y+x))
是這樣的,你想要什麼?
谷歌在查詢「set and get in haskell」上的第一個結果讓我到http://www.haskell.org/haskellwiki/State_Monad。我想翻譯的代碼看起來就是那裏給出的具體例子之一。 – 2011-05-31 19:23:36
注意,這是從C版本,在C代碼X略有不同的是修改之前* * y設定,不同時,那麼你可能需要把'(1,2)= >>修改(\( x',y) - >(x * y,y))>> =修改(\(x,y) - >(x,y + x))' – rampion 2011-05-31 20:48:19
如果您發現有一個元組的「可變」的變量,你可以在上面定義的轉換操作和「鏈」一起:
vars x y = (x,y)
setX (x,y) x' = (x', y)
setY (x,y) y' = (x, y')
appX (x,y) f = (f x, y)
appY (x,y) f = (x, f y)
app2X (x, y) f = (f x y, y)
app2Y (x, y) f = (x, f x y)
set...
設置一個值,app...
在其上應用一個函數,app2...
上在x或y的兩個值,並將其存儲應用一個函數。然後,你可以這樣做:
(vars 3 5) `setX` 14 `appY` (2*)
-- result: (14,10)
你的榜樣將成爲:
(vars 1 2) `app2X` (*) `app2Y` (+)
-- result: (2,4)
當然,這綿延「可變」一點的定義,但這種解決方案已經是一半對State
或Writer
monad。
另一種方法是考慮變量的「版本」 - 開始處的x與結尾處的x不同。例如,在C說你有,有時在華氏存儲號,然後將其轉換爲攝氏度,像這樣的變量:
temp = 40; temp = convertFtoC(temp);
那麼你可以想想這些是兩個不同的變量:
tempF = 40; tempC= convertFtoC(tempF);
不知道你的x和y,以創造更好地爲他們的名字,你可能最終在Haskell寫作:
xa = 1; ya = 2; xb = xa * ya; yb = ya + xb;
在某些情況下,可以考慮如何的好方法使您的代碼更加實用,而且不太必要。
你最終的目標是什麼? – Gabe 2011-05-31 19:10:48
我只是想修改變量的值。 – 2011-05-31 19:12:19
如果你有更多的上下文,這將有所幫助。你爲什麼要重新分配x和y?在你的代碼中,你根本不需要這樣做,所以......當翻譯僅僅是'x = 2; y = 4' – mentics 2011-05-31 19:12:48