我试图围绕ffprobe
编写一个包装器,以value
格式提取{J}格式{"format": {"format_name": value}}
。 JSON由创建的进程输出。这就是我所得到的。
import System.Process
import System.Environment
import System.IO
import Text.JSON
main = do
args <- getArgs
(_, Just out, _, p) <- createProcess
(proc "ffprobe" [args!!0, "-of", "json", "-show_format"])
{ std_out = CreatePipe }
s <- hGetContents out
--putStrLn $ show (decode s :: Result JSValue)
--waitForProcess p
--putStrLn $ valFromObj "format_name" format
-- where format = valFromObj "format" rootObj
-- (Ok rootObj) = decode s :: Result (JSObject (JSValue))
let (Ok rootObj) = decode s :: Result (JSObject (JSValue))
let (Ok format) = valFromObj "format" rootObj :: Result (JSObject (JSValue))
putStrLn format_name
where (Ok format_name) = valFromObj "format_name" format
无法编译:
[1 of 1] Compiling Main ( ffprobe.hs, ffprobe.o )
ffprobe.hs:20:59: error:
Variable not in scope: format :: JSObject JSValue
我对几件事情感到困惑,包括为什么我无法获得编译的最后一行:
为什么我无法在Ok
之后的Result
中声明::
。像:: Result Ok JSObject JSValue
?
为什么我不能在where子句中提取值?
为什么Result (JSObject (JSValue))
而不是Result JSObject JSValue
?
为什么format
超出范围?
我有一种感觉,我将IO和Result monad混合在同一个do
块中。 Result
甚至是monad吗?我是否可以在单独的do
中提取我想要的值,而无需遍历IO
do
?
答案 0 :(得分:2)
我认为你的编译错误是因为where
的位置。尝试
main = do
...
let (Ok format) = valFromObj "format" rootObj :: Result (JSObject (JSValue))
let (Ok format_name) = valFromObj "format_name" format
putStrLn format_name
where
的范围超出了do
,所以它不了解format
。
答案 1 :(得分:1)
你不能这样做:
main = do
let bar = "only visible inside main? "
return baz
where
baz = bar ++ " yes, this will break!"
这给出了:
test.hs:7:11:
Not in scope: ‘bar’
Perhaps you meant ‘baz’ (line 7)
让绑定不同于函数参数在绑定的位置不可用。 bar
以上的baz
不在Update-Database –TargetMigration: m1
范围内。与您的代码比较。