好的,所以前段时间我正在考虑根据我框中脚本的输出来确定我的xmonad中键绑定的效果。我最终决定不这样做是出于无关的原因,但我最近尝试做类似的事情,就像学习Haskell一样。
所以,鉴于功能:
test = readProcess "echo" ["-n", "gvim"] []
这会抛出,因为测试返回IO String,而spawn需要一个String。
((modm, xK_y), spawn ("xmessage " ++ test))
确定。太酷了。我知道IO操作是不可预测的,所以它们应该分开。精细。所以我在网上做了一些讨论并得到了这个(删除了xmessage并且只想通过测试的输出):
((modm, xK_y), liftIO test >>= spawn)
这更糟糕。它烦人地编译但是当我尝试绑定时没有任何反应。 (我也只用spawn" xmessage test&#34取而代之;这很有效)
所以,那时我想"也许我的功能出了问题"所以我重申它,但是从GCHi我得到" gvim"哪个是对的。那么我把它写入haskell文件:
main = test >>= putStrLn
test = readProcess "echo" ["-n", "gvim"] []
也正常工作。
那么,我哪里出错了?
编辑:解决方案是使用runProcessWithInput
而不是readProcess
。
相关链接:https://ghc.haskell.org/trac/ghc/ticket/5212 xmonad io binding not working
答案 0 :(得分:1)
<强>更新强>
显然,解决方案(请参阅下面的评论)是使用readProcessWithInput
原始答案
你这么说:
liftIO test >>= spawn
没有用,但是怎么样:
liftIO test >>= (\m -> spawn ("xmessage " ++ m))
另请注意,readProcess
返回的字符串可能会在结尾处有换行符,这可能会影响事情。
还有一些事情需要尝试:
return "gvim" >>= (\m -> spawn ("xmessage " ++ m))
import Data.Char
do { m <- liftIO test; spawn ("xmessage " ++ (filter isAlpha m)) }
第一个应该成功,因为它等同于spawn "xmessage grim"
。第二个将从test
的输出中删除任何换行符(实际上是任何非字母)。
可能会对正在发生的事情有所了解的其他一些事情:
使用以下内容创建名为/tmp/report
的脚本:
#!/bin/sh
( date; echo "/tmp/report was called with args" "$@") >> /tmp/output
使/tmp/report
可执行。
/tmp/report
并验证是否有两行附加到/tmp/output
spawn "/tmp/report A"
。通过查看预期的行是否附加到/tmp/output
来测试操作。尝试执行monad操作:
liftIO (readProcess "/tmp/report" ["B"] "") >> spawn "/tmp/report A"
(注意我们在这里使用的是>>
,而不是>>=
。)当您触发操作时,您应该会看到B
调用的报告行以及{{1}的报告行调用。
根据您在文件A
中看到的内容,您应该能够确定/tmp/output
命令是否正在执行以及readProcess
命令是否正在触发。