2017-08-27 104 views
4

如何从Shell monad中提取值?Haskell:Turtle:从壳牌获得返回值

我想排序点菜 bash的&&命令的名单,但我也想提取最终ExitCode值。

说我有下面的代码:

import   Turtle 

type Commands = [Shell ExitCode] 
run :: (MonadIO io) => Commands -> io ExitCode 
run cs = whatIsThisFunction $ Prelude.foldl (.&&.) (return ExitSuccess) cs 

whatIsThisFunction :: (MonadIO io) => Shell a -> io a 
whatIsThisFunction = undefined 

我想看看我是否能与Control.Foldl实现这一点,但没有找到一个解决方案。

任何想法?

更一般地,为什么不龟提供的功能与这种签名:

sh' :: MonadIO io => Shell a -> io a 

回答

2

sh' :: MonadIO io => Shell a -> io a是不可能的,因为Shell a可以从[a](由select :: [a] -> Shell a证明),它可以是空的来构造。

+1

使用'IO',你可以让它抛出。更好的解决方案:切换到“io(也许a)'。 – Reactormonk

+0

因此,当我被低估时,是因为答案太短或者包含事实上不正确的信息?我没有详细说明该怎么做,因为提问者已经证明他们已经知道“Control.Foldl”。因此,我的问题只是为什么那个特定的签名不是图书馆的一部分。 @Reactormonk确实表明我的“不可能”的措辞可能太强大了。我对异常的看法与我对“未定义”的看法没有多大区别。 – erisco

+0

谢谢erisco,答案很丰富。 –

4

Turtle.Shell为您提供fold :: MonadIO io => Shell a -> Fold a b -> io bControl.Foldl给你一堆Fold小号之间,其中:last :: Fold a (Maybe a)。你可以结合两者来提取最后的ExitCode你的命令返回如下所示:

import Control.Monad.IO.Class 
import Turtle.Shell as TS 
import Control.Foldl as CF 

sh' :: MonadIO io => Shell a -> io (Maybe a) 
sh' c = TS.fold c CF.last 
+0

谢谢!我正在寻找这样的东西! –

+0

顺便说一句,它看起来像一个更习惯的方式来处理龟的错误是使用异常。然后代码会更是这样的: ''' Tt.sh CMDS 'catches' [处理程序(\(E :: Tt.ProcFailed) - > Log.error $显示E) ,处理程序(\(E :: Tt.ShellFailed) - > Log.error $ show e) , - 等等 ] ''' 你同意吗? (抱歉代码布局不正确,我不知道如何在评论中做到这一点) –