Экземпляр функтора

У меня есть следующий тип newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a }, И я должен написать экземпляр Functor для этого, но я не очень понимаю, как я пытался

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (g a)

а также

instance Functor (Arr2 e1 e2) where
  fmap g = g . getArr2

что на самом деле приводит к типу

(a -> b) -> Arr2 e1 e2 a -> b

вместо желаемого

(a -> b) -> Arr2 e1 e2 a -> Arr2 e1 e2 b

Пожалуйста, помогите мне

2 ответа

Решение

Functor класс имеет в качестве определения:

class Functor f where:
    fmap :: (a -> b) -> f a -> f b
    (<$) :: a -> f b -> f a

(<$) имеет реализацию по умолчанию: (<$) = fmap . const который отлично работает

Так что это означает, что если мы введем функцию (g :: a -> b) в качестве первого аргумента и Arr2 который производит a мы должны сгенерировать Arr2 что называет это g на исходе стрелки, если он применяется.

В результате определение fmap для тебя Arr2 является:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (\x y -> g (a x y))

Или более элегантно:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (\x -> g . (a x))

Или более элегантная версия - комментирует @Alec:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 ((g .) . a)

(Вы можете конвертировать выражения в точечные, используя этот инструмент)

Ответ от Willem Van Onsem очень хороший, я просто хотел бы предложить использовать расширение языка, которое может легко создать Functor экземпляры для новых типов: DeriveFunctor,

В верхней части вашего модуля вы можете добавить:

{-# LANGUAGE DeriveFunctor #-}

Тогда вы можете автоматически получить ваш Functor пример:

newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor

Вот как бы я узнал тип fmap для этого экземпляра в GHCi:

λ > :set -XDeriveFunctor
λ > newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor
λ > :set -XTypeApplications 
λ > :t fmap @(Arr2 _ _)
fmap @(Arr2 _ _) :: (a -> b) -> Arr2 t t1 a -> Arr2 t t1 b
Другие вопросы по тегам