import { Applicative } from "@siteimprove/alfa-applicative" ; import { Declaration } from "@siteimprove/alfa-dom" ; import { Equatable } from "@siteimprove/alfa-equatable" ; import { Functor } from "@siteimprove/alfa-functor" ; import { Serializable } from "@siteimprove/alfa-json" ; import { Mapper } from "@siteimprove/alfa-mapper" ; import { Monad } from "@siteimprove/alfa-monad" ; import { Option , None } from "@siteimprove/alfa-option" ; import { Predicate } from "@siteimprove/alfa-predicate" ; import * as json from "@siteimprove/alfa-json" ; public export class Value < T = unknown > implements Functor < T > , Applicative < T > , Monad < T > , Iterable < T > , Equatable , Serializable < Value . JSON < T > > { public static of < T > ( value , source = None ) { return new Value ( value , source ) ; } private readonly _value : T ; private readonly _source : Option < Declaration > ; private constructor ( value , source ) { this . _value = value ; this . _source = source ; } public get value ( ) : T { return this . _value ; } public get source ( ) : Option < Declaration > { return this . _source ; } public map < U > ( mapper ) { return new Value ( mapper ( this . _value , this . _source ) , this . _source ) ; } public apply < U > ( mapper ) { return mapper . map ( ( mapper ) => mapper ( this . _value ) ) ; } public flatMap < U > ( mapper ) { return mapper ( this . _value , this . _source ) ; } public flatten < T > ( this ) { return this . _value ; } public includes ( value ) { return Equatable . equals ( this . _value , value ) ; } public some ( predicate ) { return predicate ( this . _value , this . _source ) ; } public none ( predicate ) { return ! predicate ( this . _value , this . _source ) ; } public equals ( value ) ; public equals ( value ) ; public equals ( value ) { return ( value instanceof Value && Equatable . equals ( value . _value , this . _value ) && value . _source . equals ( this . _source ) ) ; } public * [ Symbol . iterator ] ( ) { yield this . _value ; } public toJSON ( ) { return { value : Serializable . toJSON ( this . _value ) , source : this . _source . map ( ( source ) => source . toJSON ( ) ) . getOr ( null ) , } ; } public toString ( ) { return `${ this . _value }` ; } } public export namespace Value { export interface JSON < T = unknown > { [ key ] : json . JSON ; value : Serializable . ToJSON < T > ; source : Declaration . JSON | null ; } }