Created
March 7, 2021 11:14
-
-
Save Aster89/b2769814993cec1608e1e6e815b112de to your computer and use it in GitHub Desktop.
simple haskell program
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data Dialog = WinDialog { render :: IO (), click :: IO () } | |
| MacDialog { render :: IO (), click :: IO () } | |
| LnxDialog { render :: IO (), click :: IO () } | |
askForConfirmThenError :: IO () | |
askForConfirmThenError = do | |
print "Are you sure? [y/n]" | |
ans <- getLine | |
if ans == "n" | |
then print "Ok, (not) done" | |
else error "Ooops, I'm bugged" | |
askForMoneyThanDo :: IO () | |
askForMoneyThanDo = do | |
print "Pay first..." | |
ans <- getLine | |
let money = read ans :: Int | |
if money < 10 | |
then error "No way!" | |
else print "Ok, done." | |
createDialogFor :: String -> Dialog | |
createDialogFor "w" = WinDialog (print "Hello, I'm a Win dialog") askForConfirmThenError | |
createDialogFor "m" = MacDialog (print "Hello, I'm a Mac dialog") askForMoneyThanDo | |
createDialogFor "l" = LnxDialog (print "Hello, I'm a Lnx dialog") (print "the job is done") | |
createDialogFor _ = error "Error: unknown OS." | |
main :: IO () | |
main = do | |
print "Which os? [w/m/l]" | |
os <- getLine -- for simplicity, read from keyboard instead of from system | |
let dialog = createDialogFor os | |
render dialog | |
click dialog |
Yes, both designs are isomorphic but mine allows writing code that can call the “methods” without caring about what OS we're on (like you could do in an OO language on an object of abstract base class).
Thank you very much for your comments.
As regards the second to last comment of yours (about distinguishing the OS on the type level), I think probably it's a bit to early for me to really understand it. However, as a future reference for myself, would you mind showing me how that would translate in my example, if we say, for instance, that render
is platform-specific and click
is not?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
(This is an answer to your first comment. I'll read the other two now, as I've just refreshed the page.)
I see... So in your solution having a
targetOS :: OS
member, which is not used in this simple example, would serve the same purpose as the separate constructors in my original code, i.e. querying what OS the button is rendered for, right?