4 ms·
> It's one of the few truly purely functional languages around. No IO monads or whatsit. The IO monad, as in Haskell, can be viewed as an entirely pure constru
by wz1000 10y ago
> It's one of the few truly purely functional languages around. No IO monads or whatsit.
The IO monad, as in Haskell, can be viewed as an entirely pure construct. Its implementation is impure purely because of performance reasons. You can write your own completely pure IO type if you want, with unchanged semantics.
A basic example of this would be
data IOF r = PutStrLn String r
| GetLine (String -> r) deriving Functor
type IO = Free IOF
putStrLn s = liftF (PutStrLn s ())
getLine = liftF (GetLine id)
main :: IO ()
main = do
putStrLn "Enter your age"
age <- read <$> getLine
if age >= 18
then putStrLn "You can vote!"
else putStrLn $ unwords ["You can vote in", show (18-age), "years"]
Of course, now you need a way to interpret your IO type in order to make the machine actually do stuff. This can be achieved in two ways: You can modify the GHC RTS to allow it to interpret your IO type, or you can define an interpreter in Haskell to convert it to the IO type that the GHC RTS knows how to interpret
interpret :: IO a -> Prelude.IO a
interpret (Free (PutStrLn s r)) = Prelude.putStrLn s >> interpret r
interpret (Free (GetLine s)) = Prelude.getLine >>= interpret . s
- Profpatsch 10y agoEven though it’s very much out of context for this thread, it’s a little pearl that brought me again a little bit closer to understanding. Thanks!
- dllthomas 10y agoI believe the parent meant to say "no IO", although my knowledge of Nix is limited.