-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInteractivity.hs
More file actions
178 lines (162 loc) · 5.05 KB
/
Interactivity.hs
File metadata and controls
178 lines (162 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
module Interactivity (
input_asker,
word_asker,
word_printer,
guesser,
number_asker,
prompt,
prompt_int,
prompt_int_m,
prompt_m_int,
prompt_int_e)
where
import Data.Typeable
import System.IO
--import System.Random -- Won't work. Something broke when installing.
import Text.Read -- readMaybe
-- input_asker is an IO action that has nothing () to give out.
input_asker :: IO ()
input_asker = do
putStrLn ""
putStrLn ("Input asker:")
hSetBuffering stdin LineBuffering
user_input <- prompt (" Type something here: ")
putStrLn(" -- Type of user_input: " ++ (show (typeOf user_input)) ++ " --")
putStrLn (" You typed: \"" ++ user_input ++ "\"")
-- word_asker is an IO action whose result will be a list of Strings, so its
-- type is IO [String]. The result is extracted in main
-- (word_list <- word_asker), and word_list is a [String].
word_asker :: IO [String]
word_asker = do
putStrLn ""
putStrLn "Repeating word asker (press only enter to stop):"
putStrLn(" -- Type of word_asker: " ++ (show (typeOf word_asker)) ++ " --")
ask_for_words
ask_for_words :: IO [String]
ask_for_words = do
hSetBuffering stdin LineBuffering
user_input <- prompt (" Please enter a word: ")
if user_input == ""
then do
putStrLn (" Quit asking words.")
return []
else do
rest <- ask_for_words
return (user_input : rest)
word_printer :: [String] -> IO ()
word_printer word_list = do
if word_list == []
then do
putStrLn " There are no words."
putStrLn ""
else do
putStrLn("Word printer:")
putStrLn(" -- Type of word_list: " ++ (show (typeOf word_list)) ++ " (not IO) --")
putStrLn(" Word list concatenated into a long string:")
--let char_list = foldr (++) "" word_list
putStrLn(" " ++ (foldr (++) "" word_list))
putStrLn(" Word list, newline-separated:")
{-
let char_list2 = map (" " ++) word_list
let char_list3 = unlines char_list2
putStrLn(char_list3)
-}
putStrLn (unlines (map (" " ++) word_list))
guesser :: IO ()
guesser = do
putStrLn ("Number guesser:")
hSetBuffering stdin LineBuffering
num_str <- prompt (" Type a number between 1 and 100: ")
if num_str == ""
then do
putStrLn " Quitting number guesser."
return ()
else do
let num = read (num_str) :: Integer
if (1 <= num) && (num <= 100)
then do
putStrLn (" Guess a number between 1 and 100. (Type 0 or less to stop guessing.)")
do_guessing (num)
else do
putStrLn (" Invalid number. Stopping.")
do_guessing :: Integer -> IO ()
do_guessing num = do
user_input <- prompt (" Guess: ")
if user_input == ""
then do
putStrLn " Quitting number guesser."
return ()
else do
let guess = read user_input :: Integer
if guess < 1
then do
putStrLn (" Stopped guessing.")
else do
if guess < num
then do
putStrLn (" Too low.")
do_guessing (num)
else if guess > num
then do
putStrLn (" Too high.")
do_guessing (num)
else do
putStrLn (" You win!")
number_asker :: IO [Integer]
number_asker = do
putStrLn ""
putStrLn "Repeating number asker (type 0 or only enter to stop):"
ask_for_numbers
ask_for_numbers :: IO [Integer]
ask_for_numbers = do
maybe_int <- prompt_int(" Give an integer: ")
if (maybe_int < 1)
then return []
else do
rest <- ask_for_numbers
return (maybe_int : rest)
--------------------------------------------------------------------------------
-- Helper functions:
prompt :: String -> IO String
prompt text = do
putStr text
hFlush stdout
getLine
prompt_int :: String -> IO (Integer)
prompt_int text = do
putStr text
hFlush stdout
maybe_int <- getLine
if maybe_int == ""
then return 0
else do
let int = (read maybe_int :: Integer)
return int
prompt_int_m :: String -> IO (Integer)
prompt_int_m text = do
putStr text
hFlush stdout
something <- getLine
let read_maybe_int = readMaybe something :: Maybe Integer
putStrLn (" -- Value and type of read_maybe_int: " ++ show (read_maybe_int :: Maybe Integer) ++ " :: " ++ (show (typeOf read_maybe_int)) ++ " --")
let int_from_maybe = (maybe 0 id read_maybe_int)
putStrLn (" -- Value and type of int_from_maybe: " ++ show int_from_maybe ++ " :: " ++ (show (typeOf int_from_maybe)) ++ " --")
return int_from_maybe
prompt_m_int :: String -> IO (Maybe Integer)
prompt_m_int text = do
putStr text
hFlush stdout
something <- getLine
let read_maybe_int = readMaybe something :: Maybe Integer
return read_maybe_int
prompt_int_e :: String -> IO (Either String Integer)
prompt_int_e text = do
putStr text
hFlush stdout
something <- getLine
let read_maybe_int = readMaybe something :: Maybe Integer
if null read_maybe_int
then return (Left "Hey, an error: Invalid integer.")
else do
let int_from_maybe = (maybe 0 id read_maybe_int)
return (Right int_from_maybe)