В свободное время я изучаю Haskell, так что это вопрос начинающих.Понимание того, как Либо является экземпляром Functor
В моих показаниях я наткнулся на пример, иллюстрирующий, как Either a
сделан экземпляр Functor
:
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
Теперь я пытаюсь понять, почему карты реализации в случае конструктором Right
значения, но не в случае Left
?
Вот мое понимание:
Прежде всего позвольте мне переписать этот экземпляр в качестве
instance Functor (Either a) where
fmap g (Right x) = Right (g x)
fmap g (Left x) = Left x
Сейчас:
Я знаю, что
fmap :: (c -> d) -> f c -> f d
если подставить
f
сEither a
мы получаемfmap :: (c -> d) -> Either a c -> Either a d
типа
Right (g x)
являетсяEither a (g x)
, и типаg x
являетсяd
, поэтому у нас есть, что типRight (g x)
являетсяEither a d
, что то, что мы ожидаем отfmap
(см 2 выше)теперь, если мы посмотрим на
Left (g x)
мы можем использовать то же рассуждение, чтобы сказать, что его типEither (g x) b
, то естьEither d b
, что не то, что мы ожидаем отfmap
(см 2 выше):d
должен быть вторым параметром , а не первый! Таким образом, мы не можем сопоставитьLeft
.
Является ли мое рассуждение правильным?
Или, возможно, более очевидно бифунктор чем функтор - это бифунктора имеет операцию bimap - bimap :: (а -> т) -> (b -> n) -> fab -> fm n. Это дает вам сопоставление как с левыми, так и с правыми. В стандартной библиотеке Haskell нет класса Bifunctor, это связано с тем, что существует намного меньше Bifunctors, чем Functors «в дикой природе», хотя это удобно для Либо и пары (a, b). –
В 3, вы используете (g x) как часть типа, но это значение. Похоже, вы хотели написать 'typeof (g x)' there, а не '(g x)'. – Peaker
@stephen tetley: это интересно! Спасибо – MarcoS