我試圖構造類型的函數:提升高階函數在Haskell
liftSumthing :: ((a -> m b) -> m b) -> (a -> t m b) -> t m b
其中t
是一個單子轉換。具體而言,我有興趣這樣做:
liftSumthingIO :: MonadIO m => ((a -> IO b) -> IO b) -> (a -> m b) -> m b
我擺弄了一些哈斯克爾魔法庫,但無濟於事。我如何獲得它 是正確的,或者有一個我找不到的現成解決方案?
我試圖構造類型的函數:提升高階函數在Haskell
liftSumthing :: ((a -> m b) -> m b) -> (a -> t m b) -> t m b
其中t
是一個單子轉換。具體而言,我有興趣這樣做:
liftSumthingIO :: MonadIO m => ((a -> IO b) -> IO b) -> (a -> m b) -> m b
我擺弄了一些哈斯克爾魔法庫,但無濟於事。我如何獲得它 是正確的,或者有一個我找不到的現成解決方案?
由於IO
類型處於負值,因此無法對所有MonadIO
實例進行一般化處理。關於hackage,有一些庫針對特定實例執行此操作(monad-control,),但是他們是否在語義上聽起來有些爭議,尤其是關於它們如何處理異常和類似奇怪的事情。
編輯:有些人似乎對正面/負面的立場區分感興趣。實際上,沒有什麼可說的了(你可能已經聽說過了,但是以不同的名字)。術語來自分類的世界。
亞型背後的直覺是,「a
是b
一個亞型(我會寫a <= b
)當a
可以在任何地方使用b
有望代替」。在很多情況下確定子類型是很直接的;對於產品,(a1, a2) <= (b1, b2)
,例如a1 <= b1
和a2 <= b2
,這是一個非常簡單的規則。但是有一些棘手的案例。例如,我們應該什麼時候決定a1 -> a2 <= b1 -> b2
?
那麼,我們有一個功能f :: a1 -> a2
和一個預期功能類型爲b1 -> b2
的上下文。所以上下文將使用f
的返回值,就好像它是一個b2
,因此我們必須要求a2 <= b2
。棘手的是,上下文將提供f
與b1
,即使f
打算使用它,就好像它是一個a1
。因此,我們必須要求b1 <= a1
--這與您可能猜到的相反!我們說a2
和b2
是「協變」,或發生在「正面位置」,並且a1
和b1
是「逆變」,或發生在「負面位置」。
(快速預留:爲什麼「積極」和「消極」它是由乘法動機考慮以下兩種類型:
f1 :: ((a1 -> b1) -> c1) -> (d1 -> e1)
f2 :: ((a2 -> b2) -> c2) -> (d2 -> e2)
時候應該f1
的類型是f2
的子類型的類型嗎?陳述這些事實(練習:檢查這個使用上述規則):
e1 <= e2
d2 <= d1
c2 <= c1
。b1 <= b2
。a2 <= a1
。e1
處於d1 -> e1
正位置,其又在的f1
類型的正位置;此外,e1
總體上處於f1
類型的正面位置(因爲它是協變的,根據上述事實)。它在整個學期中的位置是它在每個子項中的位置的結果:positive * positive = positive。類似地,d1
在d1 -> e1
中處於負位置,這在整個類型中處於積極的位置。負值*正值=負值,並且d
變量確實是逆變。 b1
在類型a1 -> b1
中處於正位置,在(a1 -> b1) -> c1
中處於負位置,在整個類型中處於負位置。正面*負面*負面=正面,而且是協變的。你的想法)
現在,讓我們來看看MonadIO
類:
class Monad m => MonadIO m where
liftIO :: IO a -> m a
我們可以認爲這是子類型的顯式聲明:我們都給人一種方法,使IO a
是一個亞型m a
部分混凝土m
。馬上我們知道我們可以用IO
構造函數取正值,並將它們變成m
s。但僅此而已:我們無法將負面的IO
構造函數轉換爲m
- 我們需要一個更有趣的類。
「由於」IO「類型處於負面狀態「 - 你能詳細說明這意味着什麼以及它爲什麼重要嗎? – 2012-02-11 21:36:40
@丹伯頓我已經寫了一些關於它的文章 – 2012-02-12 01:04:59
這當然有幫助,我認爲monad-control可以讓我做足夠的修補。在這種情況下,沒有看到從「ma」到「tma」的上下文變化會如何破壞任何東西。由於缺少其他答案,我將其設置爲接受。 – zeus 2012-02-16 21:37:36
嘎!爲什麼所有的Haskell問題都這麼難?這裏沒有簡單的一點:-( – drozzy 2012-02-11 20:35:12
@drozzy:這個標籤實際上[每個答案的平均數最高的一個] [http://data.stackexchange.com/stackoverflow/query/61353/tags-with-highest-average因爲儘管它們可能並不總是那麼容易,但人們確實因爲努力而獲得獎勵。 – hammar 2012-02-12 00:02:24