48時間でSchemeを書こう/練習問題の解答
練習問題1

$演算子によって括弧の数を減らしています。最後の行は$を使わずにprint ((read (args !! 0)) + (read $ args !! 1))とも書けます。
練習問題2

またはもっと簡潔に
練習問題2

これを使うようparseStringも変更します。
練習問題2

This means that it is no longer possible to begin an atom with the hash character. This necessitates a different way of parsing #t and #f.
練習問題2

This in turn requires us to make changes to parseExpr.
練習問題2

parseNumber need to be changed to the following.
練習問題2

And the following new functions need to be added.
練習問題2

The combination of anyChar and notFollowedBy ensure that only a single character is read.
練習問題2

Note that this does not actually conform to the standard; as it stands, "space" and "newline" must be entirely lowercase; the standard states that they should be case insensitive.
練習問題2

Furthermore, add
練習問題2

before parseNumber in parseExpr and the line
練習問題2

to the LispVal type.
練習問題2

Additionally, import the Ratio module, add
練習問題2

before parseNumber in parseExpr and the line
練習問題2

to the LispVal type.
練習問題2

Real is already implemented in the Float type from Exercise 6, unless I'm mistaken.
練習問題2

Complex using Haskell's Complex type:
練習問題2

As before, import the Complex module, add
練習問題2

before parseNumber and parseFloat in parseExpr and the line
練習問題2

to the LispVal type.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

These two are analogous to parseQuoted:
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Also add
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

to parseExpr.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

I chose to go with Arrays as described in Data.Array and used list-array conversions for array construction.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

In order to use this,
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

and add the following to the LispVal type:
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Add the following lines to parseExpr; before the parser for Lists and DottedLists.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

This took a fair amount of fiddling with sepBy, endBy and friends. I started by getting the (. degenerate) dotted list to work and then went from there. This code tolerates trailing and leading spaces.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Alternative solution without a Nil constructor. spaces is the spaces from Parsec and spaces1 is the spaces from this tutorial.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Here is one way of adding a few of them.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Add symbol->string and string->symbol to the list of primitives, then:
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

This doesn't deal well with bad input, which is covered later.
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Define a helper function that takes the equal/eqv function as an argument:
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Now adjust the eqv clause:
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

And add clauses for List and DottedList to the equal function:
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Room for improvement here!
Section 4 - Recursive Parsers: Adding lists, dotted lists, and quoted datums

Another approach: