簡體   English   中英

Monad的免費Monad

[英]Free Monad of a Monad

x >>= f等於retract (liftF x >>= liftF . f)

也就是說,一個免費monad構建的monad實例是一個Functor,它也是一個Monad將擁有與原Monad相同的monad實例?

我不知道你對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 ma是同構的ma ,只是retract真的見證回縮。 請注意, liftF 不是 monad態射( returnreturn )。 免費是仿函數的類函子,但它不是在單子的類別單子(盡管retract看起來很像joinliftF看起來很像return )。

編輯:請注意,撤回意味着一種等價。 限定

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

然后考慮商類型Free ma/~ 我斷言這種類型與ma同構。 因為(liftF (retract x)) ~ x (retract . liftF . retract $ x) ==_(ma) retract x因為(retract . liftF . retract $ x) ==_(ma) retract x 因此,monad上的自由monad就是monad加上一些額外的數據。 這與當mm是幺半群時[m]m “基本相同”的說法完全相同。

也就是說,一個免費monad構建的monad實例是一個Functor,它也是一個Monad將擁有與原Monad相同的monad實例?

不。 任何仿函數的免費monad都是monad。 因此,當它存在時,它無法神奇地了解Monad實例。 並且它也不能“猜測”它,因為同一個仿函數可以以不同的方式成為Monad(例如,用於不同幺半群的作家monad)。

另一個原因是,詢問這兩個monad是否具有相同的實例是沒有多大意義的,因為它們甚至不是同構的類型。 例如,考慮作者monad上的免費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 (*)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM