2

考虑(inshell "echo A line of text." empty)有类型Shell Line

问题:如何将这种类型的值转换为Text

4

2 回答 2

5

你不能。参见*的定义Shell

newtype Shell a = Shell { _foldIO :: forall r . FoldM IO a r -> IO r }

你只能从中得到IO一些东西。但是,您可能会得到一个IO Text, 并且由于您正在做 shell 的东西,我怀疑您有一个IOmonad 上下文。

FoldM定义为*

data FoldM m a b =
   -- FoldM step initial extract
   forall x . FoldM (x -> a -> m x) (m x) (x -> m b)

因此,如果我们可以构造 aFoldM IO Line Text那么我们就可以得到我们需要的东西,我怀疑。这是一个猜测(没有经过类型检查,这有点复杂,所以我可能会犯错误)。

shellToText :: Shell Text -> IO Text
shellToText shell = foldIO shell foldm
    where
    foldm :: FoldM IO Line Text
    foldm = FoldM (\accum line -> return (accum <> lineToText line)) -- Text -> Line -> IO Text
                  (return Text.empty)                                -- IO Text
                  return                                             -- Text -> IO Text

通过使用 中的组合Control.Foldl器,这可能会大大简化,但我将把它留作练习。

(*) 如果你不熟悉,第一个forall表示rank-2 类型,第二个表示存在类型

于 2017-05-17T09:23:35.923 回答
4

strict救援功能:

strict :: MonadIO io => Shell Line -> io Text

这样你就可以

strict $ inshell "echo a line of text." empty

并在 IO Text monad 中获取 shell 命令的输出。

于 2017-08-21T22:09:47.813 回答