Нарушение законов об аппликативных функторах

Упражнения из онлайн-курса.

Предположим, что для стандартного аппликативного функтора списка оператор <*> определен стандартным образом, а pure заменен на

pure x = [x,x]

Какие законы аппликативного класса типов будут нарушены?

  • Гомоморфизм: pure g <*> pure x ≡ pure (g x)
  • Личность: pure id <*> xs ≡ xs
  • Развязка: fs <*> pure x ≡ pure ($ x) <*> fs
  • Аппликативный функтор: g <$> xs ≡ pure g <*> xs
  • Состав: (.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)

Я создал следующий файл:

newtype MyList a = MyList {getMyList :: [a]}
  deriving Show

instance Functor MyList where
  fmap f (MyList xs) = MyList (map f xs)

instance Applicative MyList where
  pure x = MyList [x,x]
  MyList gs <*> MyList xs = MyList ([g x | g <- gs, x <- xs])

fs = MyList [\x -> 2*x, \x -> 3*x]
xs = MyList [1,2]
x = 1
g = (\x -> 2*x)
us = MyList [(\x -> 2*x)]
vs = MyList [(\x -> 3*x)]

Потом попробовал:

Гомоморфизм: pure g <*> pure x ≡ pure (g x)

*Main> pure g <*> pure x :: MyList Integer
MyList {getMyList = [2,2,2,2]}
*Main> pure (g x) :: MyList Integer
MyList {getMyList = [2,2]}

Личность: pure id <*> xs ≡ xs

*Main> pure id <*> xs :: MyList Integer
MyList {getMyList = [1,2,1,2]}
*Main> xs :: MyList Integer
MyList {getMyList = [1,2]}

Развязка: fs <*> pure x ≡ pure ($ x) <*> fs

*Main> fs <*> pure x
[2,3]
*Main> pure ($ x) <*> fs
[2,3]

Аппликативный функтор: g <$> xs ≡ pure g <*> xs

*Main> g <$> xs
MyList {getMyList = [2,4]}
*Main> pure g <*> xs
MyList {getMyList = [2,4,2,4]}

Состав: (.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)

*Main> (.) <$> us <*> vs <*> xs
MyList {getMyList = [6,12]}
*Main> us <*> (vs <*> xs)
MyList {getMyList = [6,12]}

Композицию нарушать нельзя, потому что pure здесь не используется.

Кажется, что гомоморфизм, идентичность и аппликативный функтор не работают. Но когда я их выбираю в курсе, говорит, что ответ неправильный. Так кто же дурак: я или автор курса?


person user4035    schedule 01.01.2020    source источник
comment
Вы не тестировали MyList в примере обмена. Посмотрите, как распечатываются результаты, по сравнению со всеми другими примерами.   -  person David Fletcher    schedule 01.01.2020
comment
отсутствие шума - тоже сигнал.   -  person Will Ness    schedule 04.01.2020


Ответы (1)


Согласно комментарию @DavidFletcher, используя ваш код, я вижу другой результат для теста обмена:

> fs <*> pure x
MyList {getMyList = [2,2,3,3]}
> pure ($ x) <*> fs
MyList {getMyList = [2,3,2,3]}

так что вы можете перепроверить это.

person K. A. Buhr    schedule 01.01.2020
comment
Боже мой, кажется, я тестировал его по обычному списку. Теперь упражнение решено, спасибо. - person user4035; 01.01.2020