3 ms·
> Your example of `getChar >> getChar` could be simply `[getChar, getChar]`. Why can't we just compose instructions into an ordinary list? Because you can't pa
by a1369209993 6y ago
> Your example of `getChar >> getChar` could be simply `[getChar, getChar]`. Why can't we just compose instructions into an ordinary list?
Because you can't pass results from a earlier list element into the computation of a later element. You'd need a list with existentially-quantified element types such as:
{-# LANGUAGE ExistentialQuantification, GADTs #-}
foreign import ccall "exit" exit :: Int -> IO ()
infixr 1 :>
data IOList a = forall b. (:>) (a -> Act b) (IOList b)
data Act b where
Getchar :: Act Char
Print :: String -> Act ()
Exit :: Int -> Act ()
main' :: IOList ()
main' = (\_->Getchar)
:> (\c->Print ("Got '"++[c]++"'\n"))
:> (\_ -> Exit 0)
:> undefined
runio :: a -> IOList a -> IO ()
runio a (f:>fs) = flip runio fs =<< case f a of
Getchar -> getChar
Print s -> putStr s
Exit n -> exit n
main = runio () main'
where f :> g :> h :> ... is your list of instructions (rather than f : g : h : ..., which doesn't allow the response type of f to be related to the argument type of g).