Online Book Reader

Home Category

Learn You a Haskell for Great Good! - Miran Lipovaca [55]

By Root 462 0
people. Put the following in a script:

mikeD = Person {firstName = "Michael", lastName = "Diamond", age = 43}

adRock = Person {firstName = "Adam", lastName = "Horovitz", age = 41}

mca = Person {firstName = "Adam", lastName = "Yauch", age = 44}

Now let’s test our Eq instance:

ghci> mca == adRock

False

ghci> mikeD == adRock

False

ghci> mikeD == mikeD

True

ghci> mikeD == Person {firstName = "Michael", lastName = "Diamond", age = 43}

True

Of course, since Person is now in Eq, we can use it as the a for all functions that have a class constraint of Eq a in their type signature, such as elem.

ghci> let beastieBoys = [mca, adRock, mikeD]

ghci> mikeD `elem` beastieBoys

True

Show Me How to Read


The Show and Read type classes are for things that can be converted to or from strings, respectively. As with Eq, if a type’s constructors have fields, their type must be a part of Show or Read if we want to make our type an instance of them.

Let’s make our Person data type a part of Show and Read as well.

data Person = Person { firstName :: String

, lastName :: String

, age :: Int

} deriving (Eq, Show, Read)

Now we can print a person out to the terminal.

ghci> mikeD

Person {firstName = "Michael", lastName = "Diamond", age = 43}

ghci> "mikeD is: " ++ show mikeD

"mikeD is: Person {firstName = \"Michael\", lastName = \"Diamond\", age = 43}"

If we had tried to print a person on the terminal before making the Person data type part of Show, Haskell would have complained, claiming it didn’t know how to represent a person as a string. But since we first derived a Show instance for the data type, we didn’t get any complaints.

Read is pretty much the inverse type class of Show. It’s for converting strings to values of our type. Remember though, that when we use the read function, we might need to use an explicit type annotation to tell Haskell which type we want to get as a result. To demonstrate this, let’s put a string that represents a person in a script and then load that script in GHCi:

mysteryDude = "Person { firstName =\"Michael\"" ++

", lastName =\"Diamond\"" ++

", age = 43}"

We wrote our string across several lines like this for increased readability. If we want to read that string, we need to tell Haskell which type we expect in return:

ghci> read mysteryDude :: Person

Person {firstName = "Michael", lastName = "Diamond", age = 43}

If we use the result of our read later in a way that Haskell can infer that it should read it as a person, we don’t need to use type annotation.

ghci> read mysteryDude == mikeD

True

We can also read parameterized types, but we must give Haskell enough information so that it can figure out which type we want. If we try the following, we’ll get an error:

ghci> read "Just 3" :: Maybe a

In this case, Haskell doesn’t know which type to use for the type parameter a. But if we tell it that we want it to be an Int, it works just fine:

ghci> read "Just 3" :: Maybe Int

Just 3

Order in the Court!


We can derive instances for the Ord type class, which is for types that have values that can be ordered. If we compare two values of the same type that were made using different constructors, the value that was defined first is considered smaller. For instance, consider the Bool type, which can have a value of either False or True. For the purpose of seeing how it behaves when compared, we can think of it as being implemented like this:

data Bool = False | True deriving (Ord)

Because the False value constructor is specified first and the True value constructor is specified after it, we can consider True as greater than False.

ghci> True `compare` False

GT

ghci> True > False

True

ghci> True < False

False

If two values were made using the same constructor, they are considered to be equal, unless they have fields. If they have fields, the fields are compared to see which is greater. (Note that in this case, the types of the fields also must be part of the Ord type class.)

In the Maybe a data type, the Nothing value constructor is specified before the Just value constructor,

Return Main Page Previous Page Next Page

®Online Book Reader