Бесплатная Монада Монады

Является ли x >>= f эквивалентным retract (liftF x >>= liftF . f)?

То есть, является ли экземпляр монады свободной сборки монады из Functor, который также является монадой, которая будет иметь эквивалентный экземпляр монады для оригинальной Monad?

Ответы

Ответ 1

Я не знаю, каково ваше определение retract, но задано

retract :: Monad m => Free m a -> m a
retract (Pure a) = return a
retract (Impure fx) = fx >>= retract

и

liftF :: Functor f => f a -> Free f a
liftF fx = Impure (fmap Pure fx)

Обратите внимание, что (доказательства могут быть неправильными, делали это вручную и не проверяли их)

retract $ liftF x
= retract (Impure (fmap Pure x))
= (fmap Pure x) >>= retract
= (x >>= return . Pure) >>= retract
= x >>= \y -> (return $ Pure y) >>= retract
= x >>= \y -> (retract (Pure y))
= x >>= \y -> return y
= x >>= return
= x

поэтому у вас есть

retract (liftF x >>= liftF . f)
= retract ((Impure (fmap Pure x)) >>= liftF . f)
= retract $ Impure $ fmap (>>= liftF . f) $ fmap Pure x
= (fmap (>>= liftF . f) $ fmap Pure x) >>= retract
= (fmap (\y -> Pure y >>= liftF . f) x) >>= retract
= (fmap (liftF . f) x) >>= retract
= (liftM (liftF . f) x) >>= retract
= (x >>= return . liftF . f) >>= retract
= x >>= (\y -> (return $ liftF $ f y >>=  retract)
= x >>= (\y -> retract $ liftF $ f y)
= x >>= (\y -> retract . liftF $ f y)
= x >>= (\y -> f y)
= x >>= f

это не означает, что Free m a изоморфно m a, просто retract действительно свидетельствует о ретракции. Заметим, что liftF не является монадным морфизмом (return не переходит в return). Free является функтором в категории функторов, но он не является монадой в категории монад (несмотря на то, что retract очень похож на join и liftF, очень похож на return).

EDIT: Обратите внимание, что ретракция подразумевает некоторую эквивалентность. Определить

 ~ : Free m a -> Free m a -> Prop
 a ~ b = (retract a) ==_(m a) (retract b)

Затем рассмотрим фактор-тип Free m a/~. Я утверждаю, что этот тип изоморфен m a. Так как (liftF (retract x)) ~ x, потому что (retract . liftF . retract $ x) ==_(m a) retract x. Таким образом, свободная монада над монадой - это именно эта монада плюс некоторые дополнительные данные. Это точно так же, как утверждение, что [m] является "по существу тем же", что и m, когда m является m является моноидом.

Ответ 2

То есть, является ли экземпляр монады свободной сборки монады из Functor, который также является монадой, которая будет иметь эквивалентный экземпляр монады для оригинальной Monad?

Нет. Свободная монада над любым функтором является монадой. Таким образом, он не может волшебно узнать о экземпляре Monad, когда он существует. И он не может также "угадать" его, потому что один и тот же функтор может быть сделан Монадой по-разному (например, монада-писатель для разных моноидов).

Другая причина заключается в том, что нет смысла спрашивать, имеют ли эти две монады эквивалентные экземпляры, потому что они даже не изоморфны типам. Например, рассмотрите свободную монаду над монадой писателя. Это будет структура, похожая на список. Что означает, что эти два экземпляра эквивалентны?

Пример различных экземпляров монады

В случае, если приведенное выше описание неясно, здесь приведен пример типа со многими возможными экземплярами Monad.

data M a = M Integer a

bindUsing :: (Integer -> Integer -> Integer) -> M a -> (a -> M b) -> M b
bindUsing f (M n a) k =
  let M m b = k a
  in M (f m n) b

-- Any of the below instances is a valid Monad instance
instance Monad M where
  return x = M 0 x
  (>>=) = bindUsing (+)

instance Monad M where
  return x = M 1 x
  (>>=) = bindUsing (*)