карта Functor над списком в Haskell - PullRequest
0 голосов
/ 01 ноября 2018

немного запутался. fmap звучит так, как может map во всем списке Maybe, но я не могу заставить его работать, если я использую, например, fApplyFunctor = (+1) <$> [Just 1, Just 2].

То, что, кажется, прекрасно работает: map ((+1) <$>) [Just 1, Just 2, Just 3]. Это кажется излишним в том смысле, что, насколько я помню, fmap мог бы сделать это сам по себе ...

1 Ответ

0 голосов
/ 01 ноября 2018

Нет fmap означает, что вы можете отобразить над произвольным Functor типом (хорошо подумайте об этом пока как о коллекции), но вы делаете это только один "уровень функтора" глубоко. В случае, если вы fmap со списком, это в точности эквивалентно map.

fmap однако определяется для всех видов Functor с, таких как списки, Maybe с и т. Д. Здесь вы можете, таким образом, fmap в fmap отобразить два уровни:

fApplyFunctor = <b>fmap (fmap (+1))</b> [Just 1, Just 2]

Это приведет к:

Prelude> fmap (fmap (+1)) [Just 1, Just 2]
[Just 2,Just 3]
Prelude> (fmap (+1)) <$> [Just 1, Just 2]
[Just 2,Just 3]
Prelude> ((+1) <$>) <$> [Just 1, Just 2]
[Just 2,Just 3]

РЕДАКТИРОВАТЬ : как @ DanielWagner говорит, что существует тип данных Compose, который работает над двумя (или более, если Вы каскад ) Functor с и, таким образом, позволяет нам fmap два уровня глубины. Это реализовано так:

newtype Compose f g a = Compose { getCompose :: f (g a) }

instance (Functor f, Functor g) => Functor (Compose f g) where
    fmap f (Compose x) = Compose (fmap (fmap f) x)

поэтому здесь мы снова выполняем fmap на двух уровнях:

Prelude Data.Functor.Compose> getCompose ((+1) <$> Compose [Just 1, Just 2])
[Just 2,Just 3]

Но, как вы видите, требуется некоторый синтаксис, чтобы сначала обернуть данные в Compose, а затем позже "развернуть" их из Compose, так что это также требует дополнительной работы.

...