how to increment a variable in functional programming

后端 未结 4 1726
逝去的感伤
逝去的感伤 2020-11-29 07:45

How do you increment a variable in a functional programming language?

For example, I want to do:

main :: IO ()
main = do
    let i = 0
    i = i + 1
         


        
4条回答
  •  孤城傲影
    2020-11-29 08:09

    As a general rule, you don't (and you don't need to). However, in the interests of completeness.

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

    However, any answer that says you need to use something like MVar, IORef, STRef etc. is wrong. There is a purely functional way to do this, which in this small rapidly written example doesn't really look very nice.

    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)
    

提交回复
热议问题