簡短的回答是:通過什麼替換Error
所有,由ExceptT
更換ErrorT
,事情應該繼續,只要工作,因爲你不使用Error
小號方法,fail
(現在有不同的定義),或失敗模式符合do
表示法。
老Control.Monad.Error
系統和新系統Control.Monad.Except
之間的本質區別是,新的操作系統對錯誤/異常類型沒有類限制。
它被發現能夠根據多態使用任何錯誤/異常類型,比自定義字符串錯誤消息轉換有點冒險的能力更有用。
因此,類Error
已經完全消失。
作爲副作用,的fail
現在已從底層monad中解除。這也改變了do
表示法中失敗模式的影響。
舊的定義是:
fail msg = ErrorT $ return (Left (strMsg msg))
我認爲這是相當於
fail msg = throwError (strMsg msg)
如果您仍需要這種行爲,你可以改用
throwError yourIntendedErrorValue
(throwE
作品相反,如果您使用transformers
(即Control.Monad.Trans.Except
),而不是mtl
)
老do
模式匹配失敗將政策適用於
do
Just x <- myErrorTAction
...
時的動作實際上返回Nothing
。這比較尷尬,但你可以有一個明確的case
比賽(基本上脫糖吧)替換爲:
do
y <- myErrorTAction
case y of
Nothing -> throwE ...
Just x -> do
...
@DanielWagner提出以下建議,以避免額外的縮進:
do
x <- myErrorTAction >>= maybe (throwError ...) return
...
的Error
去除也消除了命名不一致的需要Control.Monad.Error
有:大多數變壓器遵循的規則是SomethingT
是變壓器的名稱,而Something
是SomethingT ... Identity
的類型別名。舊的ErrorT
打破了,因爲Error
類被用於完全不同的東西。
在新系統中,Except e = ExceptT e Identity
與其他變壓器一樣。
你說「失敗」現在有不同的作用,你能否提供一個例子,以及如何編寫等效代碼? –
@ElectricCoffee我擴大了那一點。 –
@ØrjanJohansen偶爾使用的另一種模式:'do {y < - myErrorTAction >> = maybe(throwError ...)return; ''。避免必須添加縮進級別,並且可以適應其他模式匹配;例如'do {y_ < - myErrorTAction; y < - case {沒有 - > throwError ...;只是v - >返回v}; ...}'它添加了一個縮進層,但只是暫時的(即如果你想做兩個模式匹配就不需要嵌套縮進)。 –