Почему это определение функтора дает мне ошибку?

data PPMImage a = PPMImage {width :: Integer,
                        height :: Integer,
                        magicNumber :: Integer,
                        maxColor :: Integer,
                        pixels :: [a]} deriving (Show)

instance Functor PPMImage where
    fmap f (PPMImage w h m c p) = f PPMImage w h m c (f p)

Я думаю, что понимаю весь аспект упаковки и распаковки функтора - эта ссылка, предоставленная пользователем MCH, очень помогла.

Функции и списки уже являются функторами, но этот PPMImage, который я определил, не имеет экземпляра функтора по умолчанию. Я пытаюсь определить тот, который будет просто применяться к массиву (пикселей) PPMImage, но я продолжаю получать эту ошибку:

Couldn't match expected type ‘[b]’ with actual type ‘b’
  ‘b’ is a rigid type variable bound by
    the type signature for:
      fmap :: forall a b. (a -> b) -> PPMImage a -> PPMImage b
    at New.hs:13:5-8
• In the fifth argument of ‘PPMImage’, namely ‘(f p)’
  In the expression: PPMImage w h m c (f p)
  In an equation for ‘fmap’:
      fmap f (PPMImage w h m c p) = PPMImage w h m c (f p)
• Relevant bindings include
    f :: a -> b (bound at New.hs:13:10)
    fmap :: (a -> b) -> PPMImage a -> PPMImage b (bound at New.hs:13:5)

Я не понимаю, почему это происходит, не будет ли этот функтор просто разворачивать исходный PPMImage, затем применять функцию f, а затем перепаковывать в новый PPMImage?


person hdizzle    schedule 14.05.2018    source источник


Ответы (1)


Это должно работать, если вы удалите f перед PPImage и добавите map или fmap к f p. p — это список, поэтому вы не можете применить f напрямую, он также должен быть fmapпропущен по содержимому p.

instance Functor PPMImage where
    fmap f (PPMImage w h m c p) = PPMImage w h m c (fmap f p)
person MCH    schedule 14.05.2018
comment
Разве вам не нужно map f p вместо f p? - person user202729; 14.05.2018
comment
Да, это может быть map f p или fmap f p. - person MCH; 14.05.2018
comment
Разве это f не определяет функцию, которую я собираюсь использовать в PPMImage? У меня не компилируется при удалении f - person hdizzle; 14.05.2018
comment
@ user202729 отметил. Однако я уже проголосовал за ваш ответ - person hdizzle; 14.05.2018