考虑(inshell "echo A line of text." empty)
的类型为Shell Line
。
问题:如何将此类型的值转换为Text
?
答案 0 :(得分:5)
你做不到。见the definition of Shell
*。
newtype Shell a = Shell { _foldIO :: forall r . FoldM IO a r -> IO r }
你只能从中获得IO
个东西。但是你可能得到一个IO Text
,因为你正在做shell的东西,我怀疑你有一个IO
monad上下文。
FoldM
定义为*
data FoldM m a b =
-- FoldM step initial extract
forall x . FoldM (x -> a -> m x) (m x) (x -> m b)
因此,如果我们可以构建一个FoldM 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
使用combinators in Control.Foldl
可能会大大简化这一点,但我会将其作为练习。
(*)如果您不熟悉,第一个forall
表示rank-2 type,第二个表示existential type。
答案 1 :(得分:3)
strict
有助于救援:
strict :: MonadIO io => Shell Line -> io Text
所以,你可以
strict $ inshell "echo a line of text." empty
并在IO Text monad中获取shell命令的输出。