[英]factorial function in the IO monad haskell
我正在 IO monad haskell 中执行阶乘函数。 我遵循示例 mod3 以使用 IO monad 执行阶乘函数。 我不明白为什么我的代码是错误的。 我想看看n>=1,然后对n做阶乘。 最后添加到 (n,r2) 并返回。 任何人都可以帮助理解吗?
while :: IO Bool -> IO () -> IO ()
while test body =
do b <- test
if b
then do {body ; while test body} -- same-line syntax for do
else return ()
-- remainder when integer-dividing n by 3
mod3 :: Integer -> IO Integer
mod3 n = do r <- newIORef n
while
(do {v <- readIORef r; return (v >= 3)})
(do {v <- readIORef r; writeIORef r (v-3)})
readIORef r
-- ghci> fact 4
-- (4,24)
fact :: Integer -> IO (Integer, Integer)
fact n = do r2 <- newIORef n
while
(do {v2 <- readIORef r2; return (v2 >= 1)})
(do {v2 <- readIORef r2; writeIORef r2 (v2*fact(v2-1))})
readIORef (n,r2)
在这部分代码中:
readIORef (n,r2)
(n,r2)
不是 IORef。 r2
是一个 IORef,所以你这是合法的:
readIORef r2
那么试试这个怎么样:
首先,缩进while
的参数,否则它们是新语句。
fact :: Integer -> IO (Integer, Integer)
fact n = do r2 <- newIORef n
while
(do {v2 <- readIORef r2; return (v2 >= 1)})
(do {v2 <- readIORef r2; writeIORef r2 (v2*fact(v2-1))})
readIORef (n,r2)
其次,while 的外观大致对应于命令式代码:
while r2 >= 1 :
r2 = r2 * fact(r2-1)
这毫无意义:为什么要递归调用? 您肯定知道如何用传统命令式语言以命令式风格编写阶乘; 从那开始并将其转换为 Haskell。
我看到两个阻止编译的问题。 第一个是fact (v2-1)
具有类型IO (Integer, Integer)
,但您试图将其乘以v2 :: Integer
。 您需要对fact (v2-1)
进行排序,就像对readIORef r2
排序readIORef r2
,乘以对的第二个分量。
其次,您滥用了readIORef
。 你可以在这里看到它的签名。 它需要一个IORef a
,而不是一对。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.