2015-08-19 41 views
1

此代碼給我一個錯誤:沒有實例Database.SQLite.Simple.FromField.FromField字符

67: isFileInstalled f = do 
68:    dbcon <- open "/var/lib/beaver/pkgs.db" 
69:    res <- queryNamed dbcon "SELECT * FROM files WHERE path = :path" [":path" := ("/usr/bin/getpkg" :: String)] 
70:    mapM_ putStrLn res 
71:    -- when (null res) (return()) 
72:    -- putStrLn ("File " ++ res ++ " is already installed and comes from " ++ res ++ ".") -- first res is `owner` and second is `path` 
73:    close dbcon 
74:    exit 

我得到這個錯誤:

No instance for (Database.SQLite.Simple.FromField.FromField Char) 
    arising from a use of `queryNamed' In a stmt of a 'do' block: 
    res <- queryNamed 
       dbcon 
       "SELECT * FROM files WHERE path = :path" 
       [":path" := ("/usr/bin/getpkg" :: String)] In the expression: 
    do { dbcon <- open "/var/lib/beaver/pkgs.db"; 
      res <- queryNamed 
        dbcon 
        "SELECT * FROM files WHERE path = :path" 
        [":path" := ("/usr/bin/getpkg" :: String)]; 
      mapM_ putStrLn res; 
      close dbcon; 
      .... } In an equation for `isFileInstalled': 
     isFileInstalled f 
     = do { dbcon <- open "/var/lib/beaver/pkgs.db"; 
       res <- queryNamed 
         dbcon 
         "SELECT * FROM files WHERE path = :path" 
         [":path" := ("/usr/bin/getpkg" :: String)]; 
       mapM_ putStrLn res; 

我沒有發現任何谷歌。如果它很重要,則啓用OverloadedStrings。有解決方法(或解決方法)?

回答

1

您使用res[String]

mapM_ putStrLn res 

它等同於[[Char]]。但是queryNamed返回一個行列表,所以每行都有類型[Char]。有一個instance FromField a => FromRow [a],但沒有instance FromField Char。這就是錯誤信息所說的。

我從來沒有使用過sqlite-simple,但很顯然,每一行都包含多個字段,所以您試圖獲取一行包含Char類型的多個字段。這是沒有意義的。根據實際的數據庫方案,每行應該是例如多個文本字段,那麼res可以有[[String]]。在這種情況下,您應該像下一個一樣使用它:

mapM_ (mapM_ putStrLn) (res :: [[String]]) 
+0

如果請求將被限制爲一行,這將是相同的嗎? – Piesek64

+0

@ Piesek64是的,編譯器無法知道在編譯時查詢可能返回多少行 – Yuras

+0

從您的消息和新問題中應用了修補程序。 http://pastebin.com/vtEMY60C – Piesek64