[Finishing records John Goerzen **20070815085357] { hunk ./en/book-shortcuts.xml 108 +Maybe"> +Just"> +Nothing"> hunk ./en/ch13-data.xml 7 - records hunk ./en/ch13-data.xml 230 - constructor that didn't use named fields. Then, we created a object + constructor for the type + that didn't use named fields. Then, we created a object hunk ./en/ch13-data.xml 271 - ctYear :: Int - ctMonth :: Month - ctDay :: Int - ctHour :: Int - ctMin :: Int - ctSec :: Int - ctPicosec :: Integer - ctWDay :: Day - ctYDay :: Int - ctTZName :: String - ctTZ :: Int + ctYear :: Int, + ctMonth :: Month, + ctDay :: Int, + ctHour :: Int, + ctMin :: Int, + ctSec :: Int, + ctPicosec :: Integer, + ctWDay :: Day, + ctYDay :: Int, + ctTZName :: String, + ctTZ :: Int, hunk ./en/ch13-data.xml 295 - asdf + Sometimes you don't know in advance what the types of the data you + want to store will be. For instance, our + CustomColor type used ∬s. But one could + certainly also represent color values as a &Float; or an &Integer;. + Haskell makes it possible to write generic code that + could work with any of those. Why not make the type generic as well? + + + Haskell has a well-known type that is defined just this way: &Maybe;. + It's defined in the prelude like this: + + +data Maybe a = Nothing | Just a + deriving (Eq, Ord) + + + This type is often used when the result of a function could be an + error or some other invalid result (&Nothing;), or else a real value + (&Just;). For instance, if you are searching in a list for the first + result that matches search criteria, you will either find something + or you won't. If you do, you could get back the data wrapped in + &Just;, and if you don't, you could get back &Nothing;. + + + &Maybe; is a polymorphic type because its type depends on the type of + data that is encapsulated within it. You can, in fact, encapsulate + any type of data within it. Let's look at this + with &ghci;. + + &maybe.ghci:maybe1; + + Notice here that the type of &Nothing; is Maybe a, + but the type of Just "hi" is Maybe + [Char]. The reason for this is Haskell's type inference. + &Nothing; doesn't actually encapsulate any data, so it -- by itself + -- is valid with any &Just;. You can also give it an explicit type + to force it to behave a certain way. + + + Let's push the type system and see what it lets us do with &Maybe;. + + &maybe.ghci:maybe2; + + You can compare &Nothing; to a &Just; easily enough; that comparison + will of course always be false. The comparison between two &String;s + wrapped in &Just; also works. But the type checker wisely gives an + error on the last attempt, because you're trying to compare a + &String; to a number. + + + You'll see &Maybe; used quite a bit throughout this book, and in + Haskell code in general. + + + + A Final Word on Types + + We've shown you a lot of different ways to create your own types. + Note that, by using multiple constructors, you can effectively + combine various approaches in a single type. For instance, you could + say data Foo a = Bar | Baz Int | Other a if you so + desire. This may be useful in certain situations. hunk ./en/ch13-data.xml 361 + + Association Lists + + Often times, we have to deal with data that is unordered but is indexed + by a key. For instance, a Unix administrator might have a list of + numeric UIDs and the textual usernames that they correspond to. The + utility of this list is being able to look up a textual username for a + given UID, not the order of the data. In otherwords, the UID is a key + into a database. + + + In Haskell, there are several ways to handle data that is structured in + this way. The two most common are association lists and the + Data.Map module. Association lists are handy + because they are simple. They are standard Haskell lists, so all the + functions that work on those lists work on association lists. However, + for large data sets, Data.Map will have a + considerable performance advantage over association lists. We'll + consider both in this chapter. + + addfile ./examples/ch13/maybe.ghci hunk ./examples/ch13/maybe.ghci 1 +--# maybe1 +Nothing +:t Nothing +Just "hi" +:t Just "hi" +Nothing +:t (Nothing :: Maybe [Char]) + +--# maybe2 +Nothing == Nothing +Nothing == Just "hi" +Nothing == Just 123 +Just "hi" == Just "bye" +Just "hi" == Just 123 }