Почему `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

Почему?


person Jimmy Hu    schedule 10.04.2017    source источник
comment
Уверен, вы можете попробовать это.   -  person Jimmy Hu    schedule 10.04.2017
comment
Да, я понял, что sum происходит от Data.Foldable   -  person zerkms    schedule 10.04.2017


Ответы (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#line-638) как просто (.).

Это выглядит странно, и, как будто это не должно проверять тип, потому что вы предоставляете три аргумента 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)
person Adam Wagner    schedule 10.04.2017
comment
Большое спасибо. Я новичок в хаскеле. Я не изучил экземпляр читателя, но я думаю, что вы правы. Я проверю это позже. - person Jimmy Hu; 10.04.2017
comment
Пожалуйста. Этот экземпляр обычно отображается как ((->) r) в большинстве случаев, и может быть легко пропустить, что происходит, когда он появляется где-то, просто потому, что функции чувствуют, что они должны действовать как-то особенно, но в Haskell это такой же тип, как и все остальное, так что это намного больше. более последователен, чем другие языки. - person Adam Wagner; 10.04.2017