String.Format vs ToString ()

Как правило, у вас нет (и вам не нужно). Однако в интересах полноты.

import Data.IORef
main = do
    i <- newIORef 0       -- new IORef i
    modifyIORef i (+1)    -- increase it by 1
    readIORef i >>= print -- print it

Однако любой ответ, в котором говорится, что вам нужно использовать что-то вроде MVar, IORef, STRef и т. Д., Неверно. Существует чисто функциональный способ сделать это, что в этом маленьком быстро написанном примере на самом деле выглядит не очень хорошо.

import Control.Monad.State
type Lens a b = ((a -> b -> a), (a -> b))
setL = fst
getL = snd
modifyL :: Lens a b -> a -> (b -> b) -> a
modifyL lens x f = setL lens x (f (getL lens x))
lensComp :: Lens b c -> Lens a b -> Lens a c
lensComp (set1, get1) (set2, get2) =         -- Compose two lenses
    (\s x -> set2 s (set1 (get2 s) x)        -- Not needed here
     , get1 . get2)                          -- But added for completeness

(+=) :: (Num b) => Lens a b -> Lens a b -> State a ()
x += y = do
    s <- get
    put (modifyL x s (+ (getL y s)))

swap :: Lens a b -> Lens a b -> State a ()
swap x y = do
    s <- get
    let x' = getL x s
    let y' = getL y s
    put (setL y (setL x s y') x')

nFibs :: Int -> Int
nFibs n = evalState (nFibs_ n) (0,1)

nFibs_ :: Int -> State (Int,Int) Int
nFibs_ 0 = fmap snd get -- The second Int is our result
nFibs_ n = do
    x += y       -- Add y to x
    swap x y     -- Swap them
    nFibs_ (n-1) -- Repeat
  where x = ((\(x,y) x' -> (x', y)), fst)
        y = ((\(x,y) y' -> (x, y')), snd)
13
задан dougajmcdonald 1 May 2012 в 15:40
поделиться