gpt4 book ai didi

haskell - Haskell 中的命令式循环

转载 作者:行者123 更新时间:2023-12-03 15:10:07 27 4
gpt4 key购买 nike

我试图了解 Haskell 中的 monad 系统。我以前大约 80% 的编程经验是用 C 语言编写的,但具有讽刺意味的是,Haskell 的命令式部分是最难理解的。列表操作和惰性评估更加清晰。无论如何,我想让 ghc 接受此代码。我知道代码根本没有意义。最明显的是,我通过了 Bool在哪里 IO Bool是期待。但这不是唯一的问题。我知道这是一个愚蠢的问题,但请帮助我进一步了解 Haskell 语言。

import Control.Monad

while :: Monad m => m Bool -> m () -> m ()
while cond action = do
c <- cond
when c $ do
action
while cond action

main :: IO ()
main = do
i <- 0
while (i < 10) $ do
i <- i + 1
print i

这就是我最终做到的方式。我知道 allocaArray不是必需的,但使用起来非常有趣。 Haskell 真的没有限制,非常强大。
import Control.Monad
import Data.IORef
import Foreign.Ptr
import Foreign.Storable
import Foreign.Marshal.Array

while :: Monad m => m Bool -> m () -> m ()
while cond action = do
c <- cond
if c then do
action
while cond action
else return ()

main :: IO ()
main = do
let n = 10
allocaArray n $ \p -> do
i <- newIORef 0
while (liftM (< n) (readIORef i)) $ do
i2 <- readIORef i
poke (advancePtr p i2) i2
modifyIORef i (+ 1)
writeIORef i 0
while (liftM (< n) (readIORef i)) $ do
i2 <- readIORef i
(peek $ advancePtr p i2) >>= print
modifyIORef i (+ 1)

最佳答案

这种方法的问题是 i不是可变变量。您可以使用 IORef ,但是更实用的方法是通过每次迭代传递当前状态。你可以重写你的whileM取当前值的主体和条件:

whileM :: Monad m => (a -> Bool) -> (a -> m a) -> a -> m ()
whileM test act init =
when (test init) $ (act init) >>= whileM test act

那么你可以做
whileM (< 10) (\i -> print i >> return (i + 1)) 0

关于haskell - Haskell 中的命令式循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32504352/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com