使用Aeson解析带有嵌套列表的列表

时间:2018-12-08 08:26:21

标签: haskell aeson

当尝试使用Aeson解析一些简单的JSON时,出现一个我不理解的类型错误。我有以下JSON

.welcome-area{
  position:relative;
  margin: 0;
  width: 100%;
  height: 700px;
  text-align: center;
  overflow:hidden;
   position: relative;
  z-index: 45;
}

.pic_background{
  top: 0;
  left: 0;
  position:absolute;
  z-index: 1;
  width: 100%;
  height: 700px;
  background-color: grey;
  background-size: cover;
  background-position: 0 -150px;
  background-repeat: no-repeat;
}

.main-header{
  display: block;
  text-align: center;
  width: 100%;
  height: 100px;
  color: white;
  background-color: transparent;
  position:absolute;
  z-index: 7;
}

.gradient_background{
  width: 100%;
  height: 700px;
  top: 0;
  background-image: linear-gradient(to bottom right, #002c72 , #0058e6);
  animation-name: gradient-background;
  animation-duration: 4s;
  animation-fill-mode: both;
  position: absolute;
  z-index: 2;
}

.main-header a{

}

并且我定义了以下导入和代码:

<div class="welcome-area">
  <div class=" pic_background">
    <header>
        <div class="main-header">
          <nav>
            <a href="aboutme">about me</a>
          </nav>
        </div>
    </header>
 </div>
</div>
<div class="gradient_background"></div>

当我尝试在jsonString = "[\"a\", [\"b\", \"c\"]]" :: L.ByteString 类型的字符串上使用import Data.Aeson import GHC.Generics import qualified Data.ByteString.Lazy as L data Ch = Ch { c1 :: String, c2 :: (String, String) } deriving (Show, Generic) instance FromJSON Ch 时出现错误

eitherDecode

有人可以向我解释错误并告诉我如何解析此JSON吗?

一种可行的方法是

Ch

但我宁愿直接输入文字。

1 个答案:

答案 0 :(得分:1)

如果您已经知道可以按预期进行解析的类型,那么最简单的解决方案可能就是根据该类型编写实例并进行翻译:

import Data.Aeson
import GHC.Generics
import qualified Data.ByteString.Lazy as L

data Ch = Ch {
   c1 :: String,
   c2 :: (String, String)
} deriving (Show, Generic)

instance FromJSON Ch where
    parseJSON x =
        do (a,(b,c)) <- parseJSON x
           pure (Ch a (b,c))

结果是:

*Main> :set -XOverloadedStrings
*Main> eitherDecode "[\"a\", [\"b\", \"c\"]]" :: Either String Ch
Right (Ch {c1 = "a", c2 = ("b","c")})

编辑:

更直接地使用Aeson API可能是有益的或首选的:

instance FromJSON Ch where
    parseJSON =
       withArray "Ch" $ \arr ->
       -- from Data.Aeson.Types
           if V.length arr /= 2
              -- ^ from Data.Vector
              then typeMismatch "Length should be 2" (Array arr)
                   -- ^ from Data.Aeson.Types
              else Ch <$> parseJSON (arr ! 0) <*> parseJSON ( arr ! 1 )