在Nothing
的情況下,最好通過使用decodeEither
/decodeEither'
來獲取更多信息。任一值的左側將包含一條錯誤消息,告訴您發生故障的位置。如果切換,則會看到由於error "Can't parse Repository from YAML"
一行而導致解析失敗(請參閱下面的attempt1
)。它除了一個對象外還遇到了一些東西!
最好再看看YAML包解碼到底是什麼,然後解碼到我們知道必須成功的類型 - Value。解碼,我們得到這個(見下文attempt2
):
Right (Array (fromList [Object (fromList [("group",Null),("branches",Array (fromList [String "master"])),("hash",Null),("clean",Null),("location",String "/home/gentoo-haskell"),("enabled",Null),("root",Null),("postRebuild",Null),("upstream",String "upstream master"),("task",String "rebase"),("positive",Null)])]))
看來根數據結構是一個數組,而不是一個對象。有很多方法可以解決這個問題,我選擇了一個黑客。
parseJSON (Array array) = parseJSON (array ! 0)
這使程序工作!我在下面粘貼了我的代碼。 (對於使用鏡頭的道歉;我用它來字符串和字節串快速腳本像這些之間的轉換你的程序將課程的工作完全正常,沒有它的)
{-# LANGUAGE OverloadedStrings #-}
module Lib where
import Control.Lens
import Data.ByteString
import Data.ByteString.Lens
import Data.Vector
import Data.Yaml
data Repository = Repository
{ location :: String
, task :: String
, branches :: [String]
, upstream :: String
, enabled :: Maybe Bool
, root :: Maybe Bool
, positive :: Maybe Bool
, clean :: Maybe Bool
, postRebuild :: Maybe [String]
, syncGroup :: Maybe String
, hash :: Maybe String
} deriving (Show, Eq)
instance FromJSON Repository where
parseJSON (Object v) = Repository <$>
v .: "location" <*>
v .: "task" <*>
v .: "branches" <*>
v .: "upstream" <*>
v .:? "enabled" <*>
v .:? "root" <*>
v .:? "positive" <*>
v .:? "clean" <*>
v .:? "postRebuild" <*>
v .:? "group" <*>
v .:? "hash"
parseJSON (Array array) = parseJSON (array ! 0)
raw :: String
raw = unlines [
"- group: null",
" branches:",
" - master",
" hash: null",
" clean: null",
" location: /home/gentoo-haskell",
" enabled: null",
" root: null",
" postRebuild: null",
" upstream: upstream master",
" task: rebase",
" positive: null"]
attempt1 :: Either ParseException Repository
attempt1 = decodeEither' (raw ^. packedChars)
attempt2 :: Either ParseException Value
attempt2 = decodeEither' (raw ^. packedChars)
,也許這是一個這個愚蠢行結束事情 - YAML文件是怎麼樣的?你可以嘗試複製並粘貼到一個新的文件(在Linux上)並重試? – Carsten
@Carsten複製和粘貼不起作用,即使我從Windows複製配置,但確定'[]'配置工作/ btw目前不確定,但看起來像Windows正在使用'LF'和linux在那裏使用'CRLF':S – Cynede
' []'如同空文件一樣? ...真的很難說,如果你不給我們提供關於文件和你最終解碼到的類型的更多細節 – Carsten