Почему мы используем моноид и функтор там?
Я новичок в Хаскеле.
Я не могу понять, почему мы используем моноид и 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"]]
Для других Functor
s:
> 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
тип.