Почему мы используем моноид и функтор там?

Я новичок в Хаскеле.
Я не могу понять, почему мы используем моноид и instance Functor Matrix в коде ниже и как instance Functor Matrix работает?

instance Functor Matrix where
    fmap f (M n m v) = M n m $ fmap (fmap f) v

instance Num a => Num (Matrix a) where
    fromInteger = M 1 1 . V.singleton . V.singleton . fromInteger
    negate = fmap negate
    (+) = add
    (*) = mult
    abs = fmap abs
    signum = fmap signum

scalarMult :: Num a => a -> Matrix a -> Matrix a
    scalarMult = fmap . (*)

Я знаю, что функтор необходим для negate, (*), abs, signum, но мне нужно подробное объяснение. Помоги мне, пожалуйста.

1 ответ

Решение

FunctorЭто очень простая вещь со сложным названием. Проще говоря, FunctorЭто контейнеры, которые вы можете отобразить функцию на ее значения, через fmap функция. Списки самые знакомые Functor, поскольку fmap просто map, Другой Functorс включают Maybe, IO, а также Either a,

В этом фрагменте вы определяете Matrix быть Functorтак что вы говорите компилятору, что Matrix это контейнер, который может отображать функции Для целей этого вопроса, fmap используется для определения нескольких функций в Num класс типов. Это довольно легко увидеть, как это работает (при условии, что есть fromList :: [[a]] -> Matrix a функция):

> 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"]]

Для других Functors:

> fmap (+1) [1, 2, 3]
[2, 3, 4]
> fmap (*10) (Just 1)
Just 10
> fmap (*10) Nothing
Nothing

Почему Data.Monoid импортируется в источник для Data.Matrix, это исключительно из-за функции

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

Где автор решил использовать <> вместо ++ для объединения строк, довольно обыденное использование списка Monoid, Это не имеет никакого отношения к Matrix тип.

Другие вопросы по тегам