Мы знаем, что fmap есть fmap :: Functor f => (a -> b) -> f a -> f b, а sum - sum :: (Num a, Foldable t) => t a -> a, но приведенный ниже код путает меня.
> :t (fmap sum Just)
(fmap sum Just) :: Num b => b -> b
> fmap sum Just 3
3
почему?
Ответ 1
Я думаю, что здесь, вероятно, есть два путаных бита.
Первое, самое очевидное, заключается в том, что sum работает над Foldable вещами, а не только списками. Поэтому:
Это выглядит странно, и, как будто он не должен проверять тип, потому что вы поставляете три аргумента в fmap, но на самом деле результат (fmap sum Just) является функцией:
Prelude> :t fmap sum Just
fmap sum Just :: Num b => b -> b
Если мы заменим fmap на ., все станет немного более понятным.
Prelude> (.) sum Just 3
3
Prelude> (sum . Just) 3
3