I want to make a multi choice question program in SML.
I have a text file whose content is structured as follows:
category1:Basic sml/sql
1-How many subsets does the power set of an empty set have?
A) One
B) Two
C) Three
D) Zero
Ans:A
2-What is the cardinality of the set of odd positive integers less than 10?
A) 20
B) 3
C) 5
D) 10
Ans:C
Each category has more than 5 questions
Each question belongs to a category
For each question there are 4 proposed answers followed by the answer on another line
I would like, to be able to retrieve and display to the user just the question (a random question) and the corresponding proposed answers. I have written this function that allows me to retrieve line by line all the content of my file. But I'm still stuck on how to unload a question-answer block.
fun getFromFile(file_name) =
let
val file = TextIO.openIn file_name
val text = TextIO.inputAll file
val _ = TextIO.closeIn file
in
String.tokens (fn c => c = #"\n") text
end
val table = getFromFile("question_file.txt");
How could I proceed? Is it possible to retrieve the lines of the file without passing them through a table first (retrieve the text directly)?
Find a way to encode multiple categories that contain multiple questions that contain multiple answers each. And once you have found a way to store that to a file (a file format), write a decoder. Your current decoder is a line decoder. You can encode things within things within things using lines, but you can also do it other ways.
For example, using JSON:
If relying on third-party libraries seems too difficult, you could come up with a file format yourself, e.g. a line-based one:
So given your line-based reader, loop over each line and look at the first word:
CATEGORY
, start a new category.QUESTION
, start a new question within the current category.ANSWER
orANSWER_CORRECT
, provide an option in the current question within the current category.This suggests a recursive function (since it needs to go over each line) that takes a number of parameters: The current category, the current question, and the total set of categories, questions and answers so far.
At this point you probably have to think: How do I store categories of questions with multiple answers in memory? What data type should I be using? E.g. using type aliases, you could express your data model like this:
The way SML type aliases work is that you get all of those expanded into the primitive types they consist of, so they may show up in your REPL as such:
which is considerably less readable and is one reason to use alternatives like
datatype
,abstype
or opaque modules.Going with this, however, you may define a stub like:
Now there are two sub-problems:
splitFirstWord
doesn't actually exist (yet).There is a whole lot of book-keeping of current state.
Good luck!
I don't really understand this question. Unarguably, yes?
If by "table" you mean some kind of indexable data structure like a list:
Just don't call
String.tokens (fn c => ...)
on the input.This gives you a basic
string
.Note that
table
is just the name of a value binding.If you like, you can pass it through a
chair
instead:Note also that the parenthesis around function arguments is not necessary in SML. In fact, if you think they are, you'll probably make a syntax mistake soon enough. Try to avoid redundant syntax for greater clarity.