HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

  • PackageHsYAML-0.2.1.4
  • Exports51
  • LanguageHaskell2010
  • LicenceGPL-2.0-only
  • SourceYAML.hs

Overview

0 declarations

The diagram below depicts the standard layers of a YAML 1.2 processor. This module covers the upper Native and Representation layers, whereas the Data.YAML.Event and Data.YAML.Token modules provide access to the lower Serialization and Presentation layers respectively.

image: https://yaml.org/spec/1.2.2/img/overview2.svg

Quick Start Tutorial

0 declarations

This section contains basic information on the different ways to work with YAML data using this library.

Decoding/Loading YAML document

We address the process of loading data from a YAML document as decoding.

Let's assume we want to decode (i.e. load) a simple YAML document

- name: Erik Weisz
  age: 52
  magic: True
- name: Mina Crandon
  age: 53

into a native Haskell data structure of type [Person], i.e. a list of Person records.

The code below shows how to manually define a Person record type together with a FromYAML instance:

{-# LANGUAGE OverloadedStrings #-}

import Data.YAML

data Person = Person
    { name  :: Text
    , age   :: Int
    , magic :: Bool
    } deriving Show

instance FromYAML Person where
   parseYAML = withMap "Person" $ \m -> Person
       <$> m .: "name"
       <*> m .: "age"
       <*> m .:? "magic" .!= False

And now we can decode the YAML document like so:

Example1 expression
decode "- name: Erik Weisz\n  age: 52\n  magic: True\n- name: Mina Crandon\n  age: 53" :: Either (Pos,String) [[Person]]Right [[Person {name = "Erik Weisz", age = 52, magic = True},Person {name = "Mina Crandon", age = 53, magic = False}]]

There are predefined FromYAML instance for many types.

The example below shows decoding multiple YAML documents into a list of Int lists:

Example1 expression
decode "---\n- 1\n- 2\n- 3\n---\n- 4\n- 5\n- 6" :: Either (Pos,String) [[Int]]Right [[1,2,3],[4,5,6]]

If you are expecting exactly one YAML document then you can use convenience function decode1

Example1 expression
decode1 "- 1\n- 2\n- 3\n" :: Either (Pos,String) [Int]Right [1,2,3]

Working with AST

Sometimes we want to work with YAML data directly, without first converting it to a custom data type.

We can easily do that by using the Node type, which is an instance of FromYAML, is used to represent an arbitrary YAML AST (abstract syntax tree). For example,

Example1 expression
decode1 "Name: Vijay" :: Either (Pos,String) (Node Pos)Right (Mapping (Pos {posByteOffset = 0, posCharOffset = 0, posLine = 1, posColumn = 0}) Just "tag:yaml.org,2002:map" (fromList [(Scalar (Pos {posByteOffset = 0, posCharOffset = 0, posLine = 1, posColumn = 0}) (SStr "Name"),Scalar (Pos {posByteOffset = 6, posCharOffset = 6, posLine = 1, posColumn = 6}) (SStr "Vijay"))]))

The type parameter Pos is used to indicate the position of each YAML Node in the document. So using the Node type we can easily decode any YAML document.

Pretty-printing source locations

Syntax errors or even conversion errors are reported with a source location, e.g.

Example1 expression
decode "- name: Erik Weisz\n  age: 52\n  magic: True\n- name: Mina Crandon\n  age: young" :: Either (Pos,String) [[Person]]Left (Pos {posByteOffset = 71, posCharOffset = 71, posLine = 5, posColumn = 7},"expected !!int instead of !!str")

While accurate this isn't a very convenient error representation. Instead we can use the prettyPosWithSource helper function to create more convenient error report like so

readPersons :: FilePath -> IO [Person]
readPersons fname = do
   raw <- BS.L.readFile fname
   case decode1 raw of
     Left (loc,emsg) -> do
       hPutStrLn stderr (fname ++ ":" ++ prettyPosWithSource loc raw " error" ++ emsg)
       pure []
     Right persons -> pure persons

which will then print errors in a common form such as

people.yaml:5:7: error
   |
 5 |   age: young
   |        ^
expected !!int instead of !!str

Encoding/dumping

We address the process of dumping information from a Haskell-data type(s) to a YAML document(s) as encoding.

Suppose we want to encode a Haskell-data type Person

data Person = Person
    { name :: Text
    , age  :: Int
    } deriving Show

To encode data, we need to define a ToYAML instance.


instance ToYAML Person where
    -- this generates a Node
    toYAML (Person n a) = mapping [ "name" .= n, "age" .= a]

We can now encode a node like so:

Example1 expression
encode [Person {name = "Vijay", age = 19}]"age: 19\nname: Vijay\n"

There are predefined ToYAML instances for many types. Here's an example encoding a complex Haskell Node'

Example1 expression
encode1 $ toYAML ([1,2,3], Map.fromList [(1, 2)])"- - 1\n  - 2\n  - 3\n- 1: 2\n"

Typeclass-based resolving/decoding

9 declarations
valuedecode :: FromYAML v => ByteString -> Either (Pos, String) [v]
#

Decode YAML document(s) using the YAML 1.2 Core schema

Each document contained in the YAML stream produce one element of the response list. Here's an example of decoding two concatenated YAML documents:

Example1 expression
decode "Foo\n---\nBar" :: Either (Pos,String) [Text]Right ["Foo","Bar"]

Note that an empty stream doesn't contain any (non-comment) document nodes, and therefore results in an empty result list:

Example1 expression
decode "# just a comment" :: Either (Pos,String) [Text]Right []

decode uses the same settings as decodeNode for tag-resolving. If you need a different custom parsing configuration, you need to combine parseEither and decodeNode' yourself.

The decode as well as the decodeNode functions supports decoding from YAML streams using the UTF-8, UTF-16 (LE or BE), or UTF-32 (LE or BE) encoding (which is auto-detected).

valuedecode1 :: FromYAML v => ByteString -> Either (Pos, String) v
#

Convenience wrapper over decode expecting exactly one YAML document

Example1 expression
decode1 "---\nBar\n..." :: Either (Pos,String) TextRight "Bar"
Example1 expression
decode1 "Foo\n---\nBar" :: Either (Pos,String) TextLeft (Pos {posByteOffset = 8, posCharOffset = 8, posLine = 3, posColumn = 0},"unexpected multiple YAML documents")
Example1 expression
decode1 "# Just a comment" :: Either (Pos,String) TextLeft (Pos {posByteOffset = 0, posCharOffset = 0, posLine = 1, posColumn = 0},"empty YAML stream")
classclass FromYAML a where
#

A type into which YAML nodes can be converted/deserialized

Methods

Instances26FromYAML, …
newtypenewtype Parser a
#

YAML Parser Monad used by FromYAML

See also parseEither or decode

Instances6Monad, Functor, MonadFail, Applicative, Alternative, MonadPlus
  • Monad ParserDefined in HsYAML-0.2.1.4 · Data.YAML
  • Functor ParserDefined in HsYAML-0.2.1.4 · Data.YAML
  • MonadFail ParserDefined in HsYAML-0.2.1.4 · Data.YAML

    NOTE: fail doesn't convey proper position information unless used within the with*-style helpers; consequently it's recommended to use failAtNode when not covered by the location scope of a with*-style combinator.

  • Applicative ParserDefined in HsYAML-0.2.1.4 · Data.YAML
  • Alternative ParserDefined in HsYAML-0.2.1.4 · Data.YAML
  • MonadPlus ParserDefined in HsYAML-0.2.1.4 · Data.YAML
valuetypeMismatch
  1. :: String

    descriptive name of expected data

  2. -> Node Pos

    actual node

  3. -> Parser a
#

Informative failure helper

This is typically used in fall-through cases of parseYAML like so

instance FromYAML ... where
  parseYAML ...  = ...
  parseYAML node = typeMismatch "SomeThing" node

Accessors for YAML Mappings

value(.:?) :: FromYAML a => Mapping Pos -> Text -> Parser (Maybe a)
#

Retrieve optional value in Mapping indexed by a !!str Text key.

Nothing is returned if the key is missing or points to a tag:yaml.org,2002:null node. This combinator only fails if the key exists but cannot be converted to the required type.

See also .:!.

value(.:!) :: FromYAML a => Mapping Pos -> Text -> Parser (Maybe a)
#

Retrieve optional value in Mapping indexed by a !!str Text key.

Nothing is returned if the key is missing. This combinator only fails if the key exists but cannot be converted to the required type.

NOTE: This is a variant of .:? which doesn't map a tag:yaml.org,2002:null node to Nothing.

Typeclass-based dumping

5 declarations
valueencode :: ToYAML v => [v] -> ByteString
#

Serialize YAML Node(s) using the YAML 1.2 Core schema to a lazy UTF8 encoded ByteString.

Each YAML Node produces exactly one YAML Document.

Here is an example of encoding a list of strings to produce a list of YAML Documents

Example1 expression
encode (["Document 1", "Document 2"] :: [Text])"Document 1\n...\nDocument 2\n"

If we treat the above list of strings as a single sequence then we will produce a single YAML Document having a single sequence.

Example1 expression
encode ([["Document 1", "Document 2"]] :: [[Text]])"- Document 1\n- Document 2\n"

Alternatively, if you only need a single YAML document in a YAML stream you might want to use the convenience function encode1; or, if you need more control over the encoding, see encodeNode'.

valueencode1 :: ToYAML v => v -> ByteString
#

Convenience wrapper over encode taking exactly one YAML Node. Hence it will always output exactly one YAML Document

Here is example of encoding a list of strings to produce exactly one of YAML Documents

Example1 expression
encode1 (["Document 1", "Document 2"] :: [Text])"- Document 1\n- Document 2\n"
classclass ToYAML a where
#

A type from which YAML nodes can be constructed

Methods

  • toYAML :: a -> Node ()

    Convert a Haskell Data-type to a YAML Node data type.

Instances26ToYAML, …

Accessors for encoding Mappings

Prism-style parsers

"Concrete" AST

7 declarations
newtypenewtype Doc n
#

YAML Document tree/graph

NOTE: In future versions of this API meta-data about the YAML document might be included as additional fields inside Doc

Constructors

Instances7Functor, Eq, Ord, Show, Generic, NFData, …
datadata Node loc
#

YAML Document node

Constructors

Instances8Functor, Eq, Ord, Show, Generic, FromYAML, …
datadata Scalar
#

Primitive scalar types as defined in YAML 1.2

Constructors

Instances8Eq, Ord, Show, Generic, NFData, FromYAML, …

Source locations

2 declarations
datadata Pos
#

Position in parsed YAML source

See also prettyPosWithSource.

NOTE: if posCharOffset is negative the Pos value doesn't refer to a proper location; this may be emitted in corner cases when no proper location can be inferred.

Constructors

Instances7Eq, Show, Generic, NFData, Loc, MonadError, …

Pretty prints a Pos together with the line the Pos refers and the column position.

The input ByteString must be the same that was passed to the YAML decoding function that produced the Pos value. The String argument is inserted right after the line:column: in the first line. The pretty-printed position result String will be terminated by a trailing newline.

For instance,

prettyPosWithSource somePos someInput " error" ++ "unexpected character\n"

results in

11:7: error
    |
 11 | foo: | bar
    |        ^
unexpected character

YAML 1.2 Schema resolvers

4 declarations
datadata SchemaResolver
#

Definition of a YAML 1.2 Schema

A YAML schema defines how implicit tags are resolved to concrete tags and how data is represented textually in YAML.

YAML 1.2 Schema encoders

4 declarations

Generalised AST construction

4 declarations
typetype NodeId = Word
#

Unique identifier for identifying nodes

This is allows to observe the alias/anchor-reference structure