Listing the Contents of Modules
While we haven't talked about modules much yet, I mentioned the Data.Char and
Data.List modules that are part of the standard library several times already.
It may be helpful to find out what functions, types, and type classes are
defined in these modules. The best way to do this is often to search for
Data.Char or Data.List on Hoogle. This gives you a nicely organized overview
of the different functions defined in these modules, along with their
documentation. For a quick peek from within GHCi, without any documentation, we
have :browse:
>>> :browse Data.Char
digitToInt :: Char -> Int
isLetter :: Char -> Bool
isMark :: Char -> Bool
isNumber :: Char -> Bool
isSeparator :: Char -> Bool
[...and many more lines]
or
>>> :browse Data.List
Data.List.isSubsequenceOf :: Eq a => [a] -> [a] -> Bool
(!!) :: [a] -> Int -> a
(++) :: [a] -> [a] -> [a]
(base-4.15.1.0:Data.OldList.\\) :: Eq a => [a] -> [a] -> [a]
all :: Foldable t => (a -> Bool) -> t a -> Bool
[...and many more lines]
Exercise
Which type class defines integer division operators such as div and
mod?  Which type class defines fractional division ((/))?  Which other
operations do they define?  Find out from within GHCi using :info.
Solution
div is defined in the Integral type class:
>>> :info div
type Integral :: * -> Constraint
class (Real a, Enum a) => Integral a where
  ...
  div :: a -> a -> a
  ...
    -- Defined in ‘GHC.Real’
infixl 7 `div`
This class also provides functions quot, rem, mod, quotRem,
divMod, and toInteger:
>>> :info Integral
type Integral :: * -> Constraint
class (Real a, Enum a) => Integral a where
  quot :: a -> a -> a
  rem :: a -> a -> a
  div :: a -> a -> a
  mod :: a -> a -> a
  quotRem :: a -> a -> (a, a)
  divMod :: a -> a -> (a, a)
  toInteger :: a -> Integer
  {-# MINIMAL quotRem, toInteger #-}
    -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
(/) is defined in the Fractional type class:
>>> :info (/)
type Fractional :: * -> Constraint
class Num a => Fractional a where
  (/) :: a -> a -> a
  ...
    -- Defined in ‘GHC.Real’
infixl 7 /
This class also provides functions recip and fromRational:
>>> :info Fractional
type Fractional :: * -> Constraint
class Num a => Fractional a where
  (/) :: a -> a -> a
  recip :: a -> a
  fromRational :: Rational -> a
  {-# MINIMAL fromRational, (recip | (/)) #-}
    -- Defined in ‘GHC.Real’
instance Fractional Float -- Defined in ‘GHC.Float’
instance Fractional Double -- Defined in ‘GHC.Float’
Exercise
If you load the MergeSort.hs file we used earlier in this chapter using
:load MergeSort.hs, what does :info tell you about the mergeSort
function?
Solution
>>> :load MergeSort.hs
[1 of 1] Compiling Main             ( MergeSort.hs, interpreted )
Ok, one module loaded.
>>> :info mergeSort
mergeSort :: Ord a => [a] -> [a]    -- Defined at MergeSort.hs:2:1
This says that the mergeSort function is defined in MergeSort.hs. It
takes an argument of type [a], a list of as, and produces another
list of as. However, a cannot be just any type. It must be an
instance of the Ord type class: values of type a must be comparable.
Exercise
What does :info tell you about an interactively defined value?  For
example, define x = 5 at the GHCi prompt.  Then get information about x
using :info x.
Solution
>>> x = 5
>>> :info x
x :: Num p => p     -- Defined at <interactive>:3:1
In this case, the type of x is Num p => p. We discussed before why:
Given no context to narrow down the type further, GHCi cannot determine
more than that x must have a number type. GHCi can deduce this much
because we are assigning 5 to x, which is a number.
Moreover, :info tells us that x was defined interactively, not in
any module of the standard library or in any file we may have loaded:
-- Defined at <interactive>:3:1.