Если я составлю два fmap
s
Prelude> :t (fmap.fmap)
(fmap.fmap)
:: (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
, я получу функцию, которая применяет функцию к значению внутри двух вложенных уровней структуры, f1
и f
.
И я могу его использовать - это работает, как я ожидал:
Prelude> (fmap.fmap) (+1) [[1,2]]
[[2,3]]
С предполагаемым типом, как я ожидал (2 уровня структуры вокруг результата)
Prelude> :t (fmap.fmap) (+1) [[1,2]]
(fmap.fmap) (+1) [[1,2]] :: Num b => [[b]]
Следующее не работает работай. Я тоже ожидаю этого (потому что мы не можем применить sum
к одному числу):
Prelude> (fmap.fmap) sum [[1,2]]
<interactive>:39:2: error:
• Could not deduce (Num (t0 b))
from the context: (Num (t b), Num b, Foldable t)
bound by the inferred type for ‘it’:
(Num (t b), Num b, Foldable t) => [[b]]
at <interactive>:39:2-24
The type variable ‘t0’ is ambiguous
• In the ambiguity check for the inferred type for ‘it’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the inferred type
it :: forall (t :: * -> *) b.
(Num (t b), Num b, Foldable t) =>
[[b]]
Prelude> :t (fmap.fmap) sum [[1,2]]
(fmap.fmap) sum [[1,2]] :: (Num (t b), Num b, Foldable t) => [[b]]
НО! Если я изменю один уровень структуры на тип Maybe
:
Prelude> (fmap.fmap) sum Just [1,2]
Just 3
, тогда он начнет работать, но, на мой взгляд, нарушит сигнатуру типа (fmap.fmap) :: (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
(потому что он применяет функцию sum
внутри Это первый уровень структуры, а не второй, как я ожидал). значения списка (по сравнению с числами в первых примерах):
Prelude> (fmap.fmap) sum (Just [[1,2],[2,3]])
Just [3,5]
Но что происходит здесь:
Prelude> (fmap.fmap) sum Just [1,2]
Just 3
Почему пропускается первый уровень структуры?
Какой здесь порядок применения функций?
Как Haskell определяет окончательный тип?
Prelude> :t (fmap.fmap) sum Just [1,2]
(fmap.fmap) sum Just [1,2] :: Num t => Maybe t
Почему Maybe t
, а не Maybe List t
как я понимаю (fmap.fmap)
должен определять f1 (f b)
два уровня структуры, а не один?