In this blog post, Tekmo makes the point that we can prove that ExitSuccess
exits because (I presume) it\'s like the Const
functor for
The answer is yes, but only if you use a different translation of TeletypeF
:
data TeletypeI a where
PutStrLn :: String -> TeletypeI ()
GetLine :: TeletypeI String
ExitSuccess :: TeletypeI Void
The argument of TeletypeI
is what the operation will/must provide to the rest of the program. It is the type of the argument of the continuation k
in
eval (ExitSuccess :>>= k) = ...
Since there are no values of type Void
, we can be sure that k
will never be called. (As always we'll have to ignore undefined
here.)
An equivalent type is:
data TeletypeI a where
PutStrLn :: String -> TeletypeI ()
GetLine :: TeletypeI String
ExitSuccess :: TeletypeI a
Now we would have to provide a value to k
that matches any type, and we can't do that either. This can be more practical since singleton ExitSuccess
now has the flexible type Program TeletypeI a
.
Similarly, exitSuccess
could be fixed by giving it the type IO Void
, or IO a
.