2016-11-21 89 views
5

我不知道如何實現它,我假設可能沒有辦法做到這一點。有證據或有說服力的理由說它不能做到嗎?爲什麼沒有'Contad的`MonadTransControl`實例

什麼使ContT特別?

+2

我認爲這個評論[在'ContT'的定義](https://hackage.haskell.org/package/transformers-0.5.2.0/docs/Control-Monad-Trans-Cont.html#t:ContT )是相關的:「'ContT'不是單子類的函數,許多操作不能通過它來解除」。你甚至不需要'm'成爲'Monad'就可以擁有'Monad(ContT k r m)'! – Alec

+0

@Alec這絕對會讓它變得很奇怪,但它不會將它與'MonadTransControl' –

回答

2

一般來說,您可以通過ContT r m得到的唯一值是類型m r。的Run (ContT r)類型簽名將是

Run (ContT r) = forall n b. Monad n => ContT r n b -> n (StT (ContT r) b) 

這相當於

forall n b. ((b -> n r) -> n r) -> n (StT (ContT r) b) 

唯一可能的類型爲StT (ContT r) br,但即使這樣,還有b -> n r類型的沒有可能的定義的函數傳遞到ContT。並且由於liftWith被賦予了一個需要Run (ContT r)類型值的功能,因此無法實現。

restoreT使情況更糟,因爲可能從一般ContT r m a中提取的任何值都不能轉回ContT r m a。所以你失去了來來往往。

順便說一句,這也是您無法制作ContT a MonadFix的原因。您不能將任意a轉換爲任意r,反之亦然。

相關問題