How to get normal value from IO action in Haskell

前端 未结 2 1940
名媛妹妹
名媛妹妹 2020-11-27 07:29

I have the following function:

get :: Chars -> IO Chars
get cs = do
    char <- getChar
    let (dats, idx) = (curData cs, curIndex cs)
    let (x,y:xs         


        
相关标签:
2条回答
  • 2020-11-27 07:41

    It's impossible (I lie, there is an extremely unsafe way to cheat your way out of it).

    The point is that if any I/O is performed, the behaviour and result of your programme may not depend only on explicit arguments to the used functions, thus that must be declared in the type by having it IO something.

    You use the result of an IO a action in a pure function by binding the result in main (or something called from main) and then applying the pure function, binding the result in a let,

    cs ::Chars
    cs = undefined
    
    main = do
      chars <- get cs
      let result = pureFunction chars
      print result
    

    or, if the function you want to apply to chars has type Chars -> IO b

    main = do
        chars <- get cs
        doSomething chars
    
    0 讨论(0)
  • 2020-11-27 08:01

    You can't, because that would violate referential transparency.

    IO in Haskell is made this way exactly to distinguish between actions whose result and effects may vary depending on the interaction with the environment/user and pure functions whose results are not going to change when you call them with the same input parameters.

    In order to pass the result to a pure function taking a Chars in input you have to call your IO action into another IO action, bind the result with the <- operator to a variable and pass it to your pure function. Pseudocode example:

    myPureFunction :: Chars -> ...
    
    otherAction :: Chars -> IO ()
    otherAction cs = do
      myChars <- get cs
      let pureResult = myPureFunction myChars
      ...
    

    If you're new to IO in haskell, you may wish to have a look at the Input and Output chapters in Learn You a Haskell for a Great Good! and Real World Haskell.

    There is actually a way to simply get a pure value out of an IO action, but in your case you shouldn't do it, as you're interacting with the environment: the unsafe way is ok only when you can guarantee you're not violating referential transparency.

    0 讨论(0)
提交回复
热议问题