2016-07-08 19 views
1

Ich versuche, einen Wrapper um ffprobe zu schreiben, der value in JSON des Formats {"format": {"format_name": value}} extrahiert. Der JSON wird von einem erstellten Prozess ausgegeben. Hier ist, was ich erreicht habe.Extrahieren von Daten mit Text.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 

Es irgendwie zu kompilieren:

[1 of 1] Compiling Main    (ffprobe.hs, ffprobe.o) 

ffprobe.hs:20:59: error: 
    Variable not in scope: format :: JSObject JSValue 

ich über einige Dinge bin verwirrt, einschließlich, warum kann ich nicht die letzte Zeile zu kompilieren:

  1. Warum kann‘ t Ich bestätige für Ok in der Result nach der ::. Wie :: Result Ok JSObject JSValue?
  2. Warum kann ich die Werte in einer Where-Klausel nicht extrahieren?
  3. Warum ist es Result (JSObject (JSValue)) und nicht Result JSObject JSValue?
  4. Warum ist format außerhalb des Geltungsbereichs?

Ich habe das Gefühl, ich bin die IO-und Ergebnis-Monaden zusammen in der gleichen do Block oder etwas mischen. Ist Result sogar eine Monade? Kann ich den gewünschten Wert in einem separaten do extrahieren, ohne über die ganze IOdo zu schreiten?

+0

Wenn Sie nur JSON dekodieren möchten, wissen Sie, dass es eine bekannte Haskell-Bibliothek namens ['aeson'] gibt (https://hackage.haskell.org/package/aeson-0.11.2.0/ docs/Daten-Aeson.html)? – Alec

Antwort

2

Ich denke, dass Ihr Kompilierfehler wegen der Position des where ist. Versuchen

main = do 
    ... 
    let (Ok format) = valFromObj "format" rootObj :: Result (JSObject (JSValue)) 
    let (Ok format_name) = valFromObj "format_name" format 
    putStrLn format_name 

Der Umfang der where außerhalb des do ist, damit es nicht bewusst format ist.

1

Sie können dies nicht tun:

main = do 
    let bar = "only visible inside main? " 
    return baz 
    where 
    baz = bar ++ " yes, this will break!" 

Das gibt:

test.hs:7:11: 
    Not in scope: ‘bar’ 
    Perhaps you meant ‘baz’ (line 7) 

Bindungen im Gegensatz zu Funktionsargumente Lassen Sie sind nicht in denen Bindungen. Über bar ist nicht im Bereich für baz zu verwenden. Vergleichen Sie mit Ihrem Code.