title: Decoding structured JSON arrays with circe in Scala
body: <p>Suppose I need to decode JSON arrays that look like the following, where there are a couple of fields at the beginning, some arbitrary number of homogeneous elements, and then some other field:</p>
  
  <pre><code>[ "Foo", "McBar", true, false, false, false, true, 137 ]
  </code></pre>
  
  <p>I don't know why anyone would choose to encode their data like this, but people do weird things, and suppose in this case I just have to deal with it.</p>
  
  <p>I want to decode this JSON into a case class like this:</p>
  
  <pre><code>case class Foo(firstName: String, lastName: String, age: Int, stuff: List[Boolean])
  </code></pre>
  
  <p>We can write something like this:</p>
  
  <pre><code>import cats.syntax.either._
  import io.circe.{ Decoder, DecodingFailure, Json }
  
  implicit val fooDecoder: Decoder[Foo] = Decoder.instance { c =&gt;
    c.focus.flatMap(_.asArray) match {
      case Some(fnJ +: lnJ +: rest) =&gt;
        rest.reverse match {
          case ageJ +: stuffJ =&gt;
            for {
              fn    &lt;- fnJ.as[String]
              ln    &lt;- lnJ.as[String]
              age   &lt;- ageJ.as[Int]
              stuff &lt;- Json.fromValues(stuffJ.reverse).as[List[Boolean]]
            } yield Foo(fn, ln, age, stuff)
          case _ =&gt; Left(DecodingFailure("Foo", c.history))
        }
      case None =&gt; Left(DecodingFailure("Foo", c.history))
    }
  }
  </code></pre>
  
  <p>…which works:</p>
  
  <pre><code>scala&gt; fooDecoder.decodeJson(json"""[ "Foo", "McBar", true, false, 137 ]""")
  res3: io.circe.Decoder.Result[Foo] = Right(Foo(Foo,McBar,137,List(true, false)))
  </code></pre>
  
  <p>But ugh, that's horrible. Also the error messages are completely useless:</p>
  
  <pre><code>scala&gt; fooDecoder.decodeJson(json"""[ "Foo", "McBar", true, false ]""")
  res4: io.circe.Decoder.Result[Foo] = Left(DecodingFailure(Int, List()))
  </code></pre>
  
  <p>Surely there's a way to do this that doesn't involve switching back and forth between cursors and <code>Json</code> values, throwing away history in our error messages, and just generally being an eyesore?</p>
  
  <hr>
  
  <p>Some context: questions about writing custom JSON array decoders like this in circe come up fairly often (e.g. <a href="https://gitter.im/circe/circe?at=59b53d19b59d55b823db2b" rel="noreferrer">this morning</a>). The specific details of how to do this are likely to change in an upcoming version of circe (although the API will be similar; see <a href="https://github.com/travisbrown/circe-algebra" rel="noreferrer">this experimental project</a> for some details), so I don't really want to spend a lot of time adding an example like this to the documentation, but it comes up enough that I think it does deserve a Stack Overflow Q&amp;A.</p>