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.

(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: