Почему `fmap sum Just` проверяет тип?
Мы знаем 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
вещи, а не просто списки. Следовательно:
sum (Just 3) == 3
Второй - это экземпляр функтора, который вы используете. поскольку Just
является функцией, так как это второй аргумент fmap
вы используете экземпляр средства чтения fmap, который определен здесь ( https://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC.Base.html) как простой (.)
,
Это выглядит странно, и похоже, что оно не должно проверять тип, потому что вы предоставляете три аргумента для 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
Который так же, как
sum (Just 3)