Упражнения из онлайн-курса.
Предположим, что для стандартного аппликативного функтора списка оператор <*>
определен стандартным образом, а 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
здесь не используется.
Кажется, что гомоморфизм, идентичность и аппликативный функтор не работают. Но когда я их выбираю в курсе, говорит, что ответ неправильный. Так кто же дурак: я или автор курса?