2013-09-27 39 views
4

我正嘗試使用數據類型點菜方式爲模板目的定義免費monad。我寫了一些combinators,但我卡住了。我的程序不斷髮散,我不明白爲什麼。使用免費Monads發散

考慮:

math :: Math :<: f => MathExpr a -> Free f() 
blank :: f :<: (Textual :+: Math) => Free f() -> Free (Blank k f)() 
equals :: Free (Math :+: (Blank L Math))() 
     -> Free (Math :+: (Blank R Math))() 
     -> Free Equation() 

的組合物(空白數學)具有類型:

blank . math :: (f :<: (Textual :+: Math) 
       , Math :<: f 
       ) => MathExpr a -> Free (Blank k f)() 

通知使得f必須同時比數學小於聯接文本和數學的,和更大的。所以f的唯一可能性就是Math。 (我不知道在我的部分更多的工作編譯器不能推斷出這一點,如果有的話)

當我試圖評估該問題發生:

test :: Free Equation() 
test = (hoistFree (inj :: Blank 'L Math a -> (Math :+: Blank 'L Math) a) 
    . blank 
    . (math :: MathExpr x -> Free Math()) 
    $ "hi" 
    ) 
    `equals` (math $ "world") 

這顯然循環,在100掛我的CPU %。計算結果如下:

Free (Equation (Free (DirectSum {unDirectSum = Right 

在這一點上,值被截斷並且GHCi退出。所以它顯然會發現,等於的第一個參數是在直接和的後半部分,但它似乎不能計算空白。

我所有的功能都是完整的,我在這裏沒有看到底部,但我從來沒有在固定點組合器上擅長。有任何想法嗎?

編輯:有免費的單子現在該模塊是:http://lpaste.net/93471 模塊Data.Domain是:http://lpaste.net/93472

+0

你可以把代碼放入lpaste中嗎? –

+0

@ J.Abrahamson:編輯包含代碼。 – nomen

回答

1

(我沒有足夠的代表處發表評論,所以我在做這個蹩腳的答案...)

的代碼從lpastes對我的作品(幾乎)與GHC 7.6.3和自由3.4.2

我也不得不改變一些事情,以使其類型檢測,但他們是相當簡單。

  • 用文本替換(MathExpr a)。

  • 添加-XKindSignatures和-XOverloadedStrings。

  • 對(顯示空白)派生使用獨立派生。

    導出實例(顯示(克(免克())),顯示F)=>展(坯料K克F)

我只能想象最後那些影響終止。

這些變化之後,我看到這個ghci的:

*> test 
Free (Equation (Free (DirectSum {unDirectSum = Right (Blank (Free (Math "hi" (Pure()))) (Pure()))})) (Free (DirectSum {unDirectSum = Left (Math "hello" (Pure()))})) (Pure())) 

所以,也許你使用的是外的日期/越野車組合GHC和免費的? HTH。

+0

有趣。我在我的代碼中沒有「派生」或「顯示」定義的「實例(Show(g(Free g()),Show f)=> Show(Blank kgf)」),我想知道泛型派生是否正在循環如果沒有顯示方法,它通常會顯示一個缺少錯誤的方法,謝謝! – nomen

+0

啊,通過通用派生的麻煩聽起來令人擔憂,謝謝你提及,我會研究它 – nifr

+0

我認爲我們的診斷是錯誤的。我製作了一個將Free(Things)()映射到懶惰文本構建器的「ToBuilder」類,最後我得到了一個巨大的空間泄漏。渲染編碼「hi = hello」的模板耗用了大約2000MB的ram和30%我的cpu。如果懶惰的空間泄漏是文本生成器的問題,我相信這是字符串的問題。我現在要嘗試嚴格的文本。 – nomen