如何提升STT的管道

时间:2016-02-07 03:29:44

标签: haskell monad-transformers conduit st-monad

我一直在尝试编写函数的实现:

threadSTT :: Monad m
       => (forall a. (forall s. STT s m a) -> m a)
       -> ConduitM i o (forall s. STT s m) r
       -> ConduitM i o m r
threadSTT runM (ConduitM c0) =
    ConduitM $ \rest ->
        let go (Done r) = rest r
            go (PipeM mp) = PipeM $ do
                r <- runM mp -- ERROR
                return $ go r
            go (Leftover p i) = Leftover (go p) i
            go (NeedInput x y) = NeedInput (go . x) (go . y)
            go (HaveOutput p f o) = HaveOutput (go p) (runM f) o -- ERROR
         in go (c0 Done)

foo :: Monad m => ConduitM i o (forall s. STT s m) r -> ConduitM i o m r
foo = threadSTT STT.runST

但我在每次转弯时都失败了:

Data.Array.ST

我现在怀疑实现这个功能是不可能的。

<tr class="suite">
    <td colspan="2" class="totalLabel">Total</td>
    <td class="zero number">0</td>
    <td class="skipped number">4</td>
    <td class="zero number">0</td>

    <td class="passRate suite">
        0%
    </td>
</tr>



import re
import os

if os.path.isfile(my_html_file):
        with open(my_html_file) as f:
            data = f.read()
before = '<td colspan="2" class="totalLabel">Total</td>'
after  = '</tr>'
start = data.find(before) + len(before)
stop  = data.find(after, start)
d = data[start:stop]
m = re.sub(r'\s+', '', d)
r = re.compile('<tdclass="(.*?)">(.*?)</td>')
k = r.sub(r'\2\n', m)
print k

任何人都能说到这个吗?我真的很喜欢它的工作,但如果我不能,那么我需要放弃使用0 4 0 0% 来写我的管道。

1 个答案:

答案 0 :(得分:2)

您似乎重新发明了MFunctor ConduitM个实例。您可以查看source code

管道包的作者monad hoist in this style gives surprising results when you try to unwrap a monad with side effect。在您的情况下,runST将被多次调用,因此每次管道生成项目时都会抛出状态。

您最好将Conduit i o m rConduit i o (STT s m) r的所有其他管道抬起,并在结果上调用runST。它就像transPipe lift一样简单。