Functor
s are a very simple thing that have a complicated name. Simply put, Functor
s are containers that you can map a function over its values, via the fmap
function. Lists are the most familiar Functor
, since fmap
is just map
. Other Functor
s include Maybe
, IO
, and Either a
.
In this snippet you're defining Matrix
to be a Functor
, so you're telling the compiler that Matrix
is a container that it can map functions over. For the purposes of this question, fmap
is used to define several of the functions in the Num
typeclass. It is pretty easy to see how this works (assuming there is a fromList :: [[a]] -> Matrix a
function):
> fmap id $ fromList [[1, 2], [3, 4]]
fromList [[1, 2], [3, 4]]
> fmap (+1) $ fromList [[1, 2], [3, 4]]
fromList [[2, 3], [4, 5]]
> fmap show $ fromList [[1, 2], [3, 4]]
fromList [["1", "2"], ["3", "4"]]
For other Functor
s:
> fmap (+1) [1, 2, 3]
[2, 3, 4]
> fmap (*10) (Just 1)
Just 10
> fmap (*10) Nothing
Nothing
As for why Data.Monoid
is imported in the source for Data.Matrix
, it is solely because of the function
-- | Display a matrix as a 'String' using the 'Show' instance of its elements.
prettyMatrix :: Show a => Matrix a -> String
prettyMatrix m@(M _ _ v) = unlines
[ "( " <> unwords (fmap (\j -> fill mx $ show $ m ! (i,j)) [1..ncols m]) <> " )" | i <- [1..nrows m] ]
where
mx = V.maximum $ fmap (V.maximum . fmap (length . show)) v
fill k str = replicate (k - length str) ' ' ++ str
Where the author has opted to use <>
instead of ++
for concatenating strings together, a rather mundane use of the list Monoid
. It has no relevance at all to the Matrix
type.