如果我想表达的东西像[只是一个简单的例子]:哈斯克尔 - for循环
int a = 0;
for (int x = 0; x < n; x += 1)
a = 1 - a;
我应该在Haskell做,因为它不具有可变的概念?(可能有误,请参阅:Does Haskell have variables?)
如果我想表达的东西像[只是一个简单的例子]:哈斯克尔 - for循环
int a = 0;
for (int x = 0; x < n; x += 1)
a = 1 - a;
我应该在Haskell做,因为它不具有可变的概念?(可能有误,请参阅:Does Haskell have variables?)
通常情况下,你会在程序语言有循环执行的重复与在Haskell recursion完成。在这种情况下,你应该考虑循环的结果。它似乎在0和1之间交替。在Haskell中有几种方法可以做到这一点。一种方法是
alternatingList n = take n alternating0and1
alternating0and1 = 0 : alternating1and0
alternating1and0 = 1 : alternating0and1
在Haskell中,不是使用循环,而是使用标准库函数和/或您自己的递归函数来实现所需的效果。
在您的示例代码中,您似乎将a
设置为0或1,具体取决于n
是否为偶数(如果我诚实地说,这种方式相当混乱)。为了实现在Haskell一样,你会写:
a =
if even n
then 0
else 1
有几个选项。首先,你可以重写与天真的递归问题:
loop :: Int -> Int
loop n = loop' n 0
where loop' 0 a = a
loop' n a = loop' (n - 1) (1 - a)
接下来,你可以列出的递归作为一个方面:
loop :: Int -> Int
loop n = foldr (\a _ -> 1 - a) 0 [0..n]
或者您可以使用State
来模拟一个for循环:
import Control.Monad
import Control.Monad.State
loop :: Int -> Int
loop n = execState (forM_ [0..n]
(\_ -> modify (\a -> 1 - a))) 0
另一种选择:
iterate (\a -> 1-a) 0 !! n
-- or even
iterate (1-) 0 !! n
片段iterate (\a -> 1-a) 0
会生成从0
开始获取的所有值并重复应用函数(\a -> 1-a)
的无限延迟列表。然后!! n
取第n个元素。
说实话,在这种情况下,我还会寻找一个更严格的定义iterate
,它不会产生这么多懒惰的thunk。
其他答案已经解释了如何在Haskell中以函数的方式处理这样的问题。
但是,Haskell确实具有ST动作和STRef形式的可变变量(或引用)。使用它们通常不是很漂亮,但它确实可以让你在Haskell中忠实地表达必要的变量变异代码,如果你真的想的话。
只是为了好玩,下面介绍如何使用它们来表达您的示例问题。
(下面的代码还使用whileM_从monad-loops包,为了方便起见。)
import Control.Monad.Loops
import Control.Monad.ST
import Data.STRef
-- First, we define some infix operators on STRefs,
-- to make the following code less verbose.
-- Assignment to refs.
r @= x = writeSTRef r =<< x
r += n = r @= ((n +) <$> readSTRef r)
-- Binary operators on refs. (Mnemonic: the ? is on the side of the ref.)
n -? r = (-) <$> pure n <*> readSTRef r
r ?< n = (<) <$> readSTRef r <*> pure n
-- Armed with these, we can transliterate the original example to Haskell.
-- This declares refs a and x, mutates them, and returns the final value of a.
foo n = do
a <- newSTRef 0
x <- newSTRef 0
whileM_ (x ?< n) $ do
x += 1
a @= (1 -? a)
readSTRef a
-- To run it:
main = print =<< stToIO (foo 10)
为此,您可以与[递归](http://learnyouahaskell.com/recursion)。 –
p.s. Haskell有变量。他们的行为不同于程序语言。 –
@ Code-Apprentice uuuh,like'rec x a = if x
Joe