2012-11-22 76 views
3

如果我有以下兩種Kleisli箭頭:將克利斯裏電梯提升到IO?

stdoutProcessA :: Kleisli Maybe String (IO String) 
writeToFileA :: Kleisli Maybe (FilePath, String) (IO()) 

我希望能夠寫成才,如:

compile = proc src -> do 
    output <- stdoutProcessA -< "..." 
    writeToFileA -< ("...", output) 
    ... 

這當然是不行的,因爲String不匹配與IO String。另一方面,可以將stdoutProcessAwriteToFileA定義爲Kleisli IO ...類型,但是我不能使用Kleisli Maybe ...類型的箭頭來組合它們,這是我需要的其他用途。

我對箭頭還不是很有經驗,所以我可能錯過了一些明顯的東西。怎麼會這樣做呢?

回答

5

這些箭頭沒有多大意義,對我說:

stdoutProcessA :: Kleisli Maybe String (IO String) 
writeToFileA :: Kleisli Maybe (FilePath, String) (IO()) 

它們代表與結果Maybe (IO a),當你可能是指IO (Maybe a)功能。後者類型代表IO可能失敗的行爲,而在前者中,失敗或成功完全不取決於IO

結合IOMaybe正確的方法是使用MaybeT單子轉換,就像這樣:

stdoutProcessA :: Kleisli (MaybeT IO) String String 
writeToFileA :: Kleisli (MaybeT IO) (FilePath, String)() 

如果你寫你的另一箭頭Monad m => Kleisli (MaybeT m) a b,他們應該很好地與這些那些沒有任何起重組成。另外,您也可以使用

lift' :: Monad m => Kleisli Maybe a b -> Kleisli (MaybeT m) a b 
lift' (Kleisli f) = Kleisli $ \x -> MaybeT (return $ f x) 

解除您現有Kleisli Maybe箭頭Kleisli (MaybeT IO)需要的地方。

+0

是的,實際上它們對於'Kleisli IO String String'類型'和'Kleisli IO(FilePath,String)()'來說更合理,但是我不能將它們與其他「Kleisli Maybe」類型的箭頭 - 是否有將不同單體中的克萊斯箭頭結合的方法? –