Is Haskell truly pure (is any language that deals with input and output outside the system)?

后端 未结 8 965
名媛妹妹
名媛妹妹 2020-11-29 22:38

After touching on Monads in respect to functional programming, does the feature actually make a language pure, or is it just another \"get out of jail free card\" for reason

8条回答
  •  無奈伤痛
    2020-11-29 22:53

    No, it isn't. IO monad is impure because it has side effects and mutable state (the race conditions are possible in Haskell programs so ? eh ... pure FP language don't know something like "race condition"). Really pure FP is Clean with uniqueness typing, or Elm with FRP (functional reactive programing) not Haskell. Haskell is one big lie.

    Proof :

    import Control.Concurrent 
    import System.IO as IO
    import Data.IORef as IOR
    
    import Control.Monad.STM
    import Control.Concurrent.STM.TVar
    
    limit = 150000
    threadsCount = 50
    
    -- Don't talk about purity in Haskell when we have race conditions 
    -- in unlocked memory ... PURE language don't need LOCKING because
    -- there isn't any mutable state or another side effects !!
    
    main = do
        hSetBuffering stdout NoBuffering
        putStr "Lock counter? : "
        a <- getLine
        if a == "y" || a == "yes" || a == "Yes" || a == "Y"
        then withLocking
        else noLocking
    
    noLocking = do
        counter <- newIORef 0
        let doWork = 
            mapM_ (\_ -> IOR.modifyIORef counter (\x -> x + 1)) [1..limit]
        threads <- mapM (\_ -> forkIO doWork) [1..threadsCount]
        -- Sorry, it's dirty but time is expensive ...
        threadDelay (15 * 1000 * 1000)
        val <- IOR.readIORef counter
        IO.putStrLn ("It may be " ++ show (threadsCount * limit) ++ 
            " but it is " ++ show val) 
    
    withLocking = do
        counter <- atomically (newTVar 0)
        let doWork = 
            mapM_ (\_ -> atomically $ modifyTVar counter (\x -> 
                x + 1)) [1..limit]
        threads <- mapM (\_ -> forkIO doWork) [1..threadsCount]
        threadDelay (15 * 1000 * 1000)
        val <- atomically $ readTVar counter
        IO.putStrLn ("It may be " ++ show (threadsCount * limit) ++ 
            " but it is " ++ show val)
    

提交回复
热议问题