繁体   English   中英

将 C 代码翻译成 Haskell

[英]Translate C code into Haskell

如何将这部分 C 代码翻译成 Haskell? 据我所知,我必须使用 State monad,但我不知道如何。

int x = 1;
int y = 2;
x =  x * y;
y = y + x;

假设,您有一对整数为 state:

f = do put (1,2)
       modify (\(x,y) -> (x*y,y))
       modify (\(x,y) -> (x,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

函数式语言的重点是不要这样做,创建新值或使用递归。

如果您只想打印这些值,

x = 1
y = 2
a = x*y
b = y+x

main = do
           putStrLn ("x*y: " ++ a)
           putStrLn ("y+x: " ++ b)

如果这是家庭作业,请标记为,我会更改答案。

另一种方法是考虑变量的“版本”——开头的 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;

在某些情况下,这可能是一种很好的方式来思考如何使您的代码更具功能性和更少的必要性。

如果您使用元组标识“可变”变量,则可以在其上定义转换操作并将其“链接”在一起:

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...在其上应用 function, app2...在两个值上应用 function 并将其存储在 x 或 y 中。 然后您可以执行以下操作:

(vars 3 5) `setX` 14 `appY` (2*)
-- result: (14,10)

您的示例将变为:

(vars 1 2) `app2X` (*) `app2Y` (+)  
-- result: (2,4)

当然,这有点延伸了“可变”的定义,但是这个解决方案已经是StateWriter monad 的一半。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM