簡體   English   中英

重新綁定索引monad的表示法

[英]Rebinding do notation for indexed monads

我正在關注Conor McBride的“Kleisli箭頭的令人發指的財富”論文,我在這里發布了我的代碼實現。 簡而言之,他定義了以下類型和類:

type a :-> b = forall i . a i -> b i

class IFunctor f where imap :: (a :-> b) -> (f a :-> f b)

class (IFunctor m) => IMonad m where
    skip :: a :-> m a
    bind :: (a :-> m b) -> (m a :-> m b)

data (a := i) j where
    V :: a -> (a := i) i

然后他定義了兩種類型的綁定,后者使用(:=)來限制初始索引:

-- Conor McBride's "demonic bind"
(?>=) :: (IMonad m) => m a i -> (a :-> m b) -> m b i
(?>=) = flip bind

-- Conor McBride's "angelic bind"   
(>>=) :: (IMonad m) => m (a := j) i -> (a -> m b j) -> m b i
m >>= f = bind (\(V a) -> f a) m

后者綁定工作完全正常的重新綁定do記號使用索引單子與RebindableSyntax擴展,使用下面的相應定義為returnfail

return :: (IMonad m) => a -> m (a := i) i
return = skip . V

fail :: String -> m a i
fail = error

...但問題是我不能讓前綁定(即(?>=) )起作用。 我試着定義(>>=)return到:

(>>=) :: (IMonad m) => m a i -> (a :-> m b) -> m b i
(>>=) = (?>=)

return :: (IMonad m) => a :-> m a
return = skip

然后我創建了一個保證存在特定索引的數據類型:

data Unit a where
    Unit :: Unit ()

但是,當我嘗試重新綁定do使用新定義的符號(>>=)return ,這是行不通的,如下面的例子演示:

-- Without do notation
test1 = skip Unit >>= \Unit -> skip Unit

-- With do notation
test2 = do
    Unit <- skip Unit
    skip Unit

test1類型檢查,但test2不,這是奇怪的,因為我覺得所有的RebindableSyntax所做的就是讓do記號desugar test2test1 ,所以如果test1類型檢查,那么為什么不test2 我得到的錯誤是:

Couldn't match expected type `t0 -> t1'
            with actual type `a0 :-> m0 b0'
Expected type: m0 a0 i0 -> (t0 -> t1) -> m Unit ()
  Actual type: m0 a0 i0 -> (a0 :-> m0 b0) -> m0 b0 i0
In a stmt of a 'do' block: Unit <- skip Unit
In the expression:
  do { Unit <- skip Unit;
       skip Unit }

即使我使用顯式forall語法而不是:-> type運算符,錯誤仍然存​​在。

現在,我知道使用“惡魔綁定”還有另外一個問題,那就是你無法定義(>>) ,但我仍然希望看到我能走多遠。 誰能解釋為什么我不能讓GHC去除“惡魔綁定”,即使它通常會進行類型檢查?

IIUC,GHC desugarer實際上運行 typechecker( )之后。 這就解釋了為什么你觀察到的情況在理論上是可能的。 類型檢查器可能有一些特殊的輸入規則,這些規則可能與類型檢查器對desugarred代碼的處理方式不一致。

當然,期望它們保持一致是合理的,所以我建議提交GHC錯誤。

暫無
暫無

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

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