CS 451/LLC Lab 2: Some compound symbols and their semantics
Due Mon 6 Jan 2006
This is a short lab with some easy Haskell exercises, but now with some relevance to the
(admittedly still simple) topics in lecture. As you will see in the second problem, however,
just because the syntax of a "language" is simple, it doesn't mean that the semantics is.
Problem 1 (cards)
For this problem you should define three types to help represent playing cards: suits,
values and cards (the last should be a compound of the previous two).
In particular, you should use a data type definition with
a constructor to make the cards out of suits and values. You may choose what you like for
suits and values (as far as types are concerned), but be prepared to defend your choices
from the perspective of better static error-checking (see below) as well as from the
pragmatic perspective of ease of programming. (Note that Haskell allows the definition of
type synonyms, such as type Coord = (Int,Int), but this may or may not be the
best way to define the types you want.)
Values should include the numeric cards
ace (1) through 10 plus the "face cards" jack, queen and king. Suits are the usual
clubs, diamonds, hearts and spades (ordered from least to greatest as shown).
Define two separate orderings for cards (i.e., as functions of type
Card -> Card -> Ordering),
one which places the ace low and the king high (and
otherwise as shown in order above from least to greatest) and another which
puts the ace high and the deuce low (otherwise as before). (If you know names of card games
that use these orderings, use those names to distinguish them; otherwise just use, e.g.,
acelo and acehi.)
Your orderings should be defined piecewise based on the
values and suits of the cards: i.e., you should define (or use existing) orderings on values
and suits and combine them to get orderings on cards.
Define class instances for your card type for the classes Eq, Ord, Enum, Bounded and Show
(the last is useful for printing cards out). Use whichever ordering you like for the Ord
class, but note that you only get one (i.e., as in Java's Comparable interface, the use of a
class instance in Haskell gives you a "native" ordering). You may import the List class
into your file (module) and then use the sort and sortBy functions to
do sorting on lists of cards: demonstrate this.
- Which one uses the native ordering?
- Which one allows you to specify a sorting order as a parameter,
like Java's Comparator interface?)
(By the way, use this syntax to import the List module:)
module Lab2 where
import List
... your definitions here ...
Problem 2 (dice histograms)
As we discussed in lecture, gamers use a compound syntax to describe die rolls
(die = plural of dice). A typical roll syntax would be "3d6" for a roll of three 6-sided
dice or "2d20" for a roll of two 20-sided dice. But the natural "meaning" for these rolls
is not a single outcome, but a probability distribution, i.e., an association of a (relative)
probability to each possible outcome. We can represent a (discrete, finite) probability
distribution as a bag of integers, i.e., like a set of integers, but with
overt multiplicities allowed (a bag can have several "7"s in it, unlike a set, and the
bag keeps track of how many).
Using these ideas, define:
- a data type for die rolls (e.g., you might write Roll 3 6);
- a type (not necessarily a data type) for discrete, finite probability
distributions (I recommend basing it on the concept of a bag: how can you
represent bags in Haskell? What operations will be handy?);
- a function dist which will convert a Roll into a probability
distribution;
- any operations you think would be handy on sucgh distributions, but including
at least an operation to combine two of them additively and one (call it prob
which tells
of a given predicate (boolean function on integers) how likely that predicate
will be true of a Roll, expressed as a float or ratio;
- a function hist which will convert a distribution into a histogram
(an ASCII-based chart ). For example, you might write out something like this:
12: #
11: ###
10: ######
9: ##########
8: ############
7: ############
6: ##########
5: ######
4: ###
3: #