Thanks, Dambaev, for the excellent explanation.
On Sunday, May 5, 2019 at 1:48:48 PM UTC-4, Dambaev Alexander wrote: > > > >> Admittedly I don't really understand what RT is, but from what I >> understand, in Haskell the expression like [print "ha"] is basically a >> command to the top-level interpreter (which is the language runtime) to >> perform an effect on the console (moreover, it will be evaluated on >> as-needed basis). >> > >> >> I like to imagine an interpreter that sits in the Haskell's runtime. >> Values of IO type are commands to this interpreter. Typical Haskell >> IO-based programs are building up these commands as they are being >> evaluated by the runtime. The runtime starts evaluation at the "main" >> expression defined by the programmer. >> > > You are describing "Free-monad", which is an AST interpreter in runtime, > but the actual *IO-action* in haskell is > > newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #)) > > which means, that Haskell models IO as "some function, that takes > RealWorld state, possibly modifies it and returns new RealWorld state and > some value", > `newtype` is a compile-time abstraction, which will be optimized out and > will be represented as a field, which is a function. > State# is a `primitive` datatype (provided by runtime) > (# #) is a primitive tuple > > So when you write > main :: IO () > main = putStrLn "hello" > > it is actually a function, that needs `State# RealWorld` value in order to > produce value of type () (unit): > putStrLn :: String-> IO () > putStrLn str = IO $ \state0-> > case ffi_call_to_putStrLn str of > IO next-> -- here we bind function of `ffi_call_to_putStrLn` as `next` > case next state0 of -- evaluate `next` here as it now has `s` > argument > (# state1, () #) -> (# state1, () #) -- force evaluation of > `next`, as this pattern match is strict > > main :: IO () > main = IO $ \state0-> > case putStrLn "hello" of > IO next-> -- here we bind function of `putStrLn` as `next` > case next state0 of -- evaluate `next` here as it now has `s` > argument > (# state1, () #)-> (# state1, () #) -- force evaluation of > `next`, as this pattern match is strict > > > Moreover, the ";" is itself another comand, the explicit sequencing >> command, the meaning of which is "perform the left-hand side effects, then >> perform the right-hand side effects". Such a command is a value, so it can >> be passed as a value and reused as many times as is necessary. In ATS, the >> expression like [print "ha"] evaluates right there to a void/"no value", >> and the ";" is also NOT a value at all, but rather a "shortcut" syntax to a >> "let-in-end" form. >> > > In haskell, this is (>>=) (bind) function: > > class Monad base where > (>>=) :: base left_type-> (left_type-> base right_type)-> base right_type > (>>) :: base left_type-> (left_type-> base right_type)-> base right_type > (>>) first second = first >>= \_ -> second > > instance Monad IO where > (>>=) (IO first) second = IO $ \state0-> > case first state0 of > (# state1, first_value #)-> > case second first_value of > IO next-> > next state1 > > And thus, in haskell: > > main = do > let shortcut = putStrLn "hello" > shortcut > shortcut > will print "hello" twice, as shortcut is a function, which needs 1 > argument to be evaluated. Desugared version: > > main = > let shortcut = putStrLn "hello" in > shortcut >> shortcut > > which is: > main = IO $ \state0-> > let shortcut = putStrLn "hello" in > case (shortcut >> shortcut) state0 of > (# state1, () #)-> (# state1, () #) > So, being pure, Haskell pretends that "program is started with some > unknown RealWorld state of value0 and each IO action modifies this state > and thus, this value is unique for all expressions and thus. complier > should evaluate them all instead of caching result of the first evaluation > of `hostcut`" > > > > -- You received this message because you are subscribed to the Google Groups "ats-lang-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-users+unsubscr...@googlegroups.com. To post to this group, send email to ats-lang-users@googlegroups.com. Visit this group at https://groups.google.com/group/ats-lang-users. To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/e7795895-6198-4c2a-a7d2-76ab9183905a%40googlegroups.com.