如果我想表達的東西像[只是一個簡單的例子]:哈斯克爾 - 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