For Development HEAD DRAFTSearch (procedure/syntax/module):

11.42 srfi.189 - MaybeとEither、オプショナルなコンテナ型

Module: srfi.189

MaybeとEitherは、任意個の値を「ラップ」する変更不可なコンテナ型です。 Maybeは値が「有効な値が無い」という状況で使えます (これは「ゼロ個の値を生成する」とは異なります)。 Eitherは「正常動作の時の値」と「エラー時の値」を区別したい状況で使えます。

Haskellのような関数型言語に親しんでいるなら、これらの型については既に ご存知でしょう。これらの型はモナドで使うととても便利です。 例えば、処理の連なりをまるで失敗が起きないかのように書きながら、 もし失敗が起きたら自動的に残りの処理がキャンセルされて失敗情報が帰ってくる、 というふうにできます。

Maybeは2つの型、JustとNothingのユニオン型です。 Justは有効な値(複数可)をラップし、Nothingは「有効な値がない」ことを示します。 Eitherは2つの型、RightとLeftのユニオン型です。 Rightは有効な値(複数可)をラップしLeftはエラー時の情報をラップします。

Schemeには多値があるので、他の言語と違ってJust、Right、Leftは 任意個の値を持てることに注意してください。 例えば2つの値を返す手続きfをMaybeモナドの圏に持ち上げた手続きmfは、 2つの値を持つJustNothingを返すようになります。 ほとんどの場合は単一の値を扱うことになるでしょうが、 リファレンスを読む際には多値の場合の可能性を頭に置いておいてください。


11.42.1 型と述語

Class: <maybe>
Class: <just>
Class: <nothing>

{srfi.189} Maybe型のクラスです。<just><nothing><maybe>のサブクラスです。 <just>のインスタンスは任意個の値(ペイロード)を保持できます。 <nothing>のインスタンスは値を保持しません。

<maybe>クラス自体は抽象クラスで、それ自身のインスタンスは作りません。 <just><nothing>のインスタンスはそれぞれ コンストラクタjustおよびnothingで作ります。

Class: <either>
Class: <right>
Class: <left>

{srfi.189} Either型のクラスです。<right><left><either>のサブクラスです。 どちらのインスタンスは任意個の値(ペイロード)を保持できます。 慣習として、<right>は正常な計算結果を運ぶのに使われ、 <left>は異常が生じた時に何が異常かの情報を運ぶのに使われます。

<either>クラス自体は抽象クラスで、それ自身のインスタンスは作りません。 <right><left>のインスタンスはそれぞれ コンストラクタrightおよびleftで作ります。

Function: maybe? obj
Function: just? obj
Function: nothing? obj

[SRFI-189]{srfi.189} 型検査述語です。 それぞれ、objがMaybe, Just, Nothingである場合に#tを、 そうでなければ#fを返します。

Function: either? obj
Function: right? obj
Function: left? obj

[SRFI-189]{srfi.189} 型検査述語です。 それぞれ、objがEither, Right, Leftである場合に#tを、 そうでなければ#fを返します。

Function: maybe= elt= maybe1 maybe …

[SRFI-189]{srfi.189} Maybeについての等価判定述語です。NothingはNothingのみと等価であり、 Justはその対応するペイロード同士が全てelt=で比較して等価な場合にのみ 等価です。

Function: either= elt= either1 either …

[SRFI-189]{srfi.189} Eitherについての等価判定述語です。 Rightは同じペイロードを持つRightのみと、 Leftは同じペイロードを持つLeftのみと等価です。 ペイロード同士はelt=で比較されます。


11.42.2 コンストラクタ

Function: just obj …

[SRFI-189]{srfi.189} obj …をペイロードに持つJustのインスタンスを返します。

Function: nothing

[SRFI-189]{srfi.189} Nothingのインスタンスを返します。

Function: right obj …
Function: left obj …

[SRFI-189]{srfi.189} obj …をペイロードに持つ、それぞれRightとLeftのインスタンスを返します。

Function: list->just objs
Function: list->right objs
Function: list->left objs

[SRFI-189]{srfi.189} リストで与えられるオブジェクトをペイロードに持つ、Just、Right、Left のインスタンスをそれぞれ返します。

Function: maybe->either maybe obj …

[SRFI-189]{srfi.189} maybe引数はMaybeでなければなりません。 引数がJustの場合は。同じペイロードを持つRightが、 Nothingの場合は、obj …をペイロードに持つLeftが返されます。

Function: either->maybe either

[SRFI-189]{srfi.189} either引数はEitherでなければなりません。 引数がRightの場合は。同じペイロードを持つJustが、 Leftの場合はNothingが返されます。

Function: either-swap either

[SRFI-189]{srfi.189} either引数はEitherでなければなりません。 引数がRightの場合は。同じペイロードを持つLeftが、 Leftの場合は同じペイロードを持つRightが返されます。、


11.42.3 アクセサ

Function: maybe-ref maybe failure :optional success

[SRFI-189]{srfi.189} maybe引数はMaybeでなければなりません。 それがNothingなら、手続きfailureが引数なしで末尾呼び出しされます。 Justの場合は手続きsuccessが、Justのペイロードを引数として末尾呼び出しされます。 successが省略された場合はvaluesが使われます。

(maybe-ref (just 1 2) (^[] (error 'huh?)) +)
  ⇒ 3
Function: either-ref either failure :optional success

[SRFI-189]{srfi.189} either引数はEitherでなければなりません。 それがLeftなら、手続きfailureが、 Rightの場合は手続きsuccessがペイロードを引数として末尾呼び出しされます。 successが省略された場合はvaluesが使われます。

Function: maybe-ref/default maybe default …

[SRFI-189]{srfi.189} maybe引数はMaybeでなければなりません。 それがNothingなら、default …が値として返されます。 Justの場合はそのペイロードが値として返されます。

(maybe-ref/default maybe obj ...)
 ≡ (maybe-ref maybe (^[] (values obj ...)))
Function: either-ref/default maybe default …

[SRFI-189]{srfi.189} either引数はEitherでなければなりません。 それがLeftなら、そのペイロードは捨てられ、 default …が値として返されます。 Rightの場合はそのペイロードが値として返されます。

(either-ref/default either obj ...)
 ≡ (either-ref either (^ _ (values obj ...)))
Function: maybe-join maybe

[SRFI-189]{srfi.189} maybeがNothingならそのまま返されます。 それがJustで、一つだけの値を持ち、その値がMaybeならそれが返されます。 それ以外の場合はエラーが投げられます。

Function: either-join either

[SRFI-189]{srfi.189} eitherがLeftならそのまま返されます。 それがRightで、一つだけの値を持ち、その値がEitherならそれが返されます。 それ以外の場合はエラーが投げられます。

Function: maybe-bind maybe mproc mproc2 …

[SRFI-189]{srfi.189} モナドのbindです。maybeはMaybeでなければならず、 mproc mproc2 …のそれぞれはMaybeを返す手続きでなければなりません。

maybeがNothingならそれがそのまま返されます。 Justの場合は、そのペイロードを引数としてmprocが呼ばれます。 mproc2 …があれば同様に操作が繰り返されます。

(maybe-bind m p p2)
  ≡ (maybe-bind (maybe-bind m p) p2)
Function: either-bind either mproc mproc2 …

[SRFI-189]{srfi.189} モナドのbindです。eitherはEithereでなければならず、 mproc mproc2 …のそれぞれはEitherを返す手続きでなければなりません。

eitherがLeftならそれがそのまま返されます。 Rightの場合は、そのペイロードを引数としてmprocが呼ばれます。 mproc2 …があれば同様に操作が繰り返されます。

(either-bind e p p2)
  ≡ (either-bind (either-bind e p) p2)
Function: maybe-compose mproc mproc2 …
Function: either-compose mproc mproc2 …

[SRFI-189]{srfi.189} mproc mproc2 … はそれぞれ、ゼロ個以上の引数を取り Maybe/Eitherを返す手続きでなければなりません。 返り値は、ゼロ個以上の引数を取りMaybe/Eitherを返す手続きになります。

作られた手続きが呼ばれると、まずmprocが呼ばれます。それがNothing/Left を返した場合、あるいはもうmprocが無い場合はそれがそのまま返されます。 Just/Rightの場合は、そのペイロードを引数として次のmprocが呼ばれ、 それが繰り返されます。

(maybe-bind m p p2 ...)
  ⇒ (maybe-ref m (^[] (nothing))
              (maybe-compose p p2 ...))

11.42.4 シーケンス操作

MaybeとEitherは、0個または1個の要素を持つシーケンスとみなせます。 この視点からMaybe/Eitherを扱う手続きがいくつかあります (註: この用途においては、複数のペイロードはひとまとめにして1要素と して扱われます。手続き呼び出しや手続きからのリターンが、いくつ引数や返り値が あってもワンステップと考えられるのと同様です)。

Function: maybe-length maybe
Function: either-length either

[SRFI-189]{srfi.189} maybe/eitherがNothing/Leftなら0を、 Just/Rightなら1を返します。 引数がMaybe/Eitherでなければエラーが投げられます。

Function: maybe-filter pred maybe
Function: either-filter pred either obj …

[SRFI-189]{srfi.189} maybe/eitherがNothing/Leftなら、 それぞれNothingもしくはobj …をペイロードに持つLeftを返します。 maybe/eitherがJust/Rightなら、そのペイロードを引数として predを呼び、それが真の値を返したら maybe/eitherがそのまま返されます。 そうでなければNothingもしくはobj …をペイロードに持つLeftが返されます。

Function: maybe-remove pred maybe
Function: either-remove pred either obj …

[SRFI-189]{srfi.189} predの意味が逆になることを除いて、 maybe-filter/either-filterと同じです。

Function: maybe-sequence mappable cmap :optional aggregator
Function: either-sequence mappable cmap :optional aggregator

[SRFI-189]{srfi.189} この手続きは、Maybe/Eitherのコレクションを、 コレクションのMaybe/Eitherへと変換します。 入力となるコレクションと出力となるコレクションの型は違っていても構いません。

これは、Haskell的なタイプシグネチャを使った方が(厳密ではありませんが) わかりやすいでしょう。 Container xを何らかの型xのオブジェクトのコレクション、 a*を任意の型の多値とします。

Mappable   = Container Maybe a*
CMap       = ((Maybe a* -> b) -> Container Maybe a* -> Container' b
Aggregator = a* -> b

maybe-sequence :: Mappable -> CMap -> Aggregator -> Container' b

入力コンテナの要素が全てJustであれば、 cmapは最初の引数である手続き入力のコンテナmappableの各要素に適用し、 結果を別のコンテナに集積します。mappableと型があってさえいれば、 各コンテナの型は任意です。 例えばmappableにMaybeのベクタ、cmapvector-mapを 渡すことができます。この場合、ContainerContainer'の型は どちらもベクタです。あるいは、mappableはMaybeのリストで、 cmap(cut map-to <string> <> <>)を渡すこともできます。 この場合、Containerはリスト、Container'は文字列となります。

a*bの型はaggregator手続きにより決定されます。 デフォルトの値はlistです。

(use gauche.sequence) ; generic map
(map-sequence (vector (just 'a 'b) (just 'c 'd 'e) (just 'f))
              map
              vector)
  ⇒ #<Just (#(a b) #(c d e) #(f))>

入力コンテナの中にNothingがあればそれがそのまま返されます。

either-sequenceの動作も、Just/NothingをRight/Leftに入れ替える だけで同様です。入力シーケンスにLeftが含まれていた場合は 最初のLeftがそのまま返されます。

Function: maybe-map proc maybe
Function: either-map proc either

[SRFI-189]{srfi.189} maybe/eitherがNothing/Leftならばそれがそのまま返されます。 Just/Rightである場合は、そのペイロードがprocに渡され、結果が Just/Rightにくるんで返されます。

(maybe-map quotient&remainder (just 18 4))
 ⇒ #<Just 4 2>
Function: maybe-for-each proc maybe
Function: either-for-each proc either

[SRFI-189]{srfi.189} maybe/eitherがNothing/Leftならば何もしません。 Just/Rightならば、そのペイロードを引数としてprocが呼ばれます。 procの結果は捨てられます。

Function: maybe-fold kons knil maybe
Function: either-fold kons knil either

[SRFI-189]{srfi.189} maybe/eitherがNothing/Leftならknilが返されます。 Just/Rightならそのペイロードおよびknilを引数としてkonsが呼ばれ、 その結果が返されます。

(maybe-fold vector 'z (just 'a 'b))
  ⇒ #(a b z)
Function: maybe-unfold p f g seed …
Function: either-unfold p f g seed …

[SRFI-189]{srfi.189} まず、終了述語pseed …を引数として呼ばれます。 それが真の値を返したら、Nothingおよびseed …をペイロードとする Leftがそれぞれ返されます。 そうでなければ次のシードを生成するgseed …を引数として 呼ばれます。gは引数と同じ数の値を返さねばなりません。 gの戻り値はpに渡され終了条件がチェックされます。 もしpが真の値を返さなかったらエラーが投げられます (シーケンスとしてのMaybe/Eitherはたかだか1個の要素しか持てないので)。 そうでなければ、seed …が値生成手続きfに渡され、 その結果がJust/Rightにラップされて返されます。


11.42.5 プロトコル変換

Function: maybe->list maybe

[SRFI-189]{srfi.189} maybeがJustならば、そのペイロードのリストが返されます。 Nothingならば空リストが返されます。 (戻り値が空リストになるのは、maybeがNothingである場合と ゼロ個のペイロードを持つJustである場合があります)

これは「シーケンスとしてのMaybe」をリストに変換するものではないことに 注意してください。シーケンスとして見た場合、Justはつねに一つだけの 要素を持ちます。ただ、その要素が多値である場合があります。 この手続きは概念的にはvalues->listに似ています。

Function: list->maybe lis

[SRFI-189]{srfi.189} lisが空リストならNothingが、そうでなければ lisの各要素をペイロードとして持つJustが返されます。

(list->maybe (maybe->list x))は恒等関数ではないことに 注意して下さい。xがゼロ個のペイロードを持つJustの場合、 この式はNothingを返します。

Function: either->list either

[SRFI-189]{srfi.189} maybeがRightならば、そのペイロードのリストが返されます。 Leftならば空リストが返されます。 (戻り値が空リストになるのは、eitherがLeftである場合と ゼロ個のペイロードを持つRightである場合があります)

Function: list->either lis obj …

[SRFI-189]{srfi.189} lisが空リストならobj …をペイロードとして持つLeftが、 そうでなければlisの各要素をペイロードとして持つRightが返されます。

Function: maybe->truth maybe

[SRFI-189]{srfi.189} maybeがNothingなら#fが、ペイロードとして値をひとつだけ持つJustなら その値が返されます。ペイロードに1つ以外の値を持つJustだった場合は エラーが投げられます。任意のペイロードを扱いたい場合は 下のmaybe->list-truthを使って下さい。

#fが帰って来た場合に、元がNothingだったのか#fを値として 持つJustだったのか区別できないことに注意してください。 この手続きは、Maybeインタフェースと、従来の「Maybe的な」インタフェースとの 橋渡しをします。例えばfindは述語を満たす要素が無かった場合に #fを返しますが、「述語を満たす要素」が#fである場合を扱えません。 その意味で「Maybe的な」インタフェースは不完全なんですが、それを期待している 従来のコードにMaybeを使った結果を返したい場合にこの手続きが使えます。

Function: truth->maybe obj

[SRFI-189]{srfi.189} obj#fならNothingを、そうでなければ objをペイロードに持つJustを返します。

(truth->maybe (maybe->truth x))は恒等関数ではないことに注意して下さい。 x(just #f)だった場合、この式の値はNothingになります。

Function: either->truth either

[SRFI-189]{srfi.189} eitherがLeftなら#fが、 ひとつの値を持つRightならその値が返されます。

eitherが一つ以外の値を持つRightであった場合はエラーが投げられます。 任意個のペイロードを持つRightを扱いたい場合は either->list-truthが使えます。

Function: truth->either obj fail-obj …

[SRFI-189]{srfi.189} obj#fならfail-obj …をペイロードに持つLeftが、 そうでなければobjをペイロードに持つRightが返されます。

Function: maybe->list-truth maybe

[SRFI-189]{srfi.189} maybe->listと同じように、maybeがNothingの場合は#fを 返しますが、Justの場合はペイロードのリストを返します。

Function: list-truth->maybe lis-or-false

[SRFI-189]{srfi.189} 引数はリストか#fでなければなりません。 引数が#fならばNothingが返されます。 引数がリストの場合は、それらの各要素をペイロードとするJustが返されます。

(list-truth->maybe (maybe->list-truth x))はxの恒等写像です。

Function: either->list-truth either

[SRFI-189]{srfi.189} either->listと同じように、eitherがRightならば そのペイロードの値のリストが返されます。 しかしeitherがLeftの場合は#fが返されます。

Function: list-truth->either lis-or-false fail-objs …

[SRFI-189]{srfi.189} list-or-false引数はリストか#fでなければなりません。 #fの場合は、fail-objs …をペイロードとするLeftが、 リストの場合はその各要素をペイロードとするRightが返されます。

Function: maybe->generation maybe

[SRFI-189]{srfi.189} maybeがNothingならEOFを、 ペイロードをひとつ持つJustならその値を返します。 それ以外の場合はエラーが投げられます。

Function: generation->maybe obj

[SRFI-189]{srfi.189} objがEOFならNothingが、 そうでなければobjをペイロードとするJustが返されます。

Function: either->generation either

[SRFI-189]{srfi.189} eitherがLeftならEOFを、 ペイロードをひとつ持つRightならその値を返します。 それ以外の場合はエラーが投げられます。

Function: generation->either obj fail-objs …

[SRFI-189]{srfi.189} objがEOならfail-objs …をペイロードに持つLeftが、 そうでなければobjをペイロードに持つRightが返されます。

Function: maybe->values maybe

[SRFI-189]{srfi.189} maybeがJustなら、そのペイロードを多値で返します。 Nothingならゼロ個の値を返します。 (ゼロ個のペイロードを持つJustだった場合もゼロ個の値が返されることに注意してください)。

Function: values->maybe producer

[SRFI-189]{srfi.189} まず手続きproducerを引数なしで呼び出します。 それがゼロ個の値を返した場合はNothingが、そうでなければ 値をペイドーロとするJustが返されます。

Function: either->values either

[SRFI-189]{srfi.189} eitherがRightなら、そのペイロードを多値で返します。 Leftならゼロ個の値を返します。 (ゼロ個のペイロードを持つRightだった場合もゼロ個の値が返されることに注意してください)。

Function: values->either producer fail-obj …

[SRFI-189]{srfi.189} まず手続きproducerを引数なしで呼び出します。 それがゼロ個の値を返した場合は、fail-obj …をペイロードとする Leftが、そうでなければ値をペイドーロとするRightが返されます。

Function: maybe->two-values maybe

[SRFI-189]{srfi.189} maybeがひとつのペイロードを持つJustであれば、その値と#tを 2つの値として返します。 maybeがNothingならば、2つの#fを返します。 maybeがそれ以外の場合はエラーが投げられます。

2つ目の値によって、呼び出し側は引数がNothingだったのか #fをペイロードに持つJustだったのかを区別できます。

Function: two-values->maybe producer

[SRFI-189]{srfi.189} maybe->two-valuesの逆です。 手続きproducerが引数無しで呼ばれます。それは2つの値を返さねばなりません。 2つ目の値が真ならば、1つ目の値をペイロードとするJustが、 そうでなければNothingが返されます(1つ目の値は捨てられます)。

Function: exception->either pred thunk

[SRFI-189]{srfi.189} 例外ハンドラを設定したうえで、手続きthunkが引数なしで呼ばれます。 thunkが例外を投げた場合、そのコンディションオブジェクトがpredに 渡されます。predが真を返した場合は、コンディションがLeftにラップされて 返されます。pred#fを返した場合は同じ例外が再び投げられます。 例外が投げられなかった場合は、thunkの戻り値がRightにラップされて 返されます。


11.42.6 Syntactic utilities

Macro: maybe-if mtest then else

[SRFI-189]{srfi.189} If the mtest expression yields a Just, evaluates then. If the mtest expression yeilds a Nothing, evaluates else. If the mtest expression doesn’t produce a Maybe, an error is thrown.

Macro: maybe-and maybe …
Macro: either-and either …

[SRFI-189]{srfi.189} Evaluates maybe/either from left to right, as far as each yields a Just/Right. If every expression yields a Just/Right, the last one is returned. If it encounters an expression that yields a Nothing/Left, it stops evaluating the rest of expressions and returns the Nothing/Left.

If expressions yield something other than Maybe/Either, an error is thrown.

Macro: maybe-or maybe …
Macro: either-or either …

[SRFI-189]{srfi.189} Evaluates maybe/either from left to right, as far as each yields a Nothing/Left. If it encounters an expression that yields a Just/Right, it stops evaluating the rest of expressions and returns it.

If expressions yield something other than Maybe/Either, an error is thrown.

Macro: maybe-let* ( claw … ) body …
Macro: either-let* ( claw … ) body …

[SRFI-189]{srfi.189} This is a Maybe/Either version of and-let*.

Each claw can be either one of the following forms:

identifier

The identifier’s value is taken. It must be a Maybe/an Either, or an error is signaled. If it is a Just/Right, evaluation proceeds to the next claw. If it is a Nothing/Left, evaluation stops and the value is returned immediately.

(identifier expression)

The expression is evaluated. It must yield a Maybe/an Either, or an error is signaled. If it is a Just/Right, identifier is bound to its payload, and the rest of claws and body are processed with the scope of identifier. If it is a Nothing/Left, evaluation stops and the value is returned immediately. An error is signaled if a Just/Right doesn’t carry exactly one value.

( expression )

The expression is evaluated. It must yield a Maybe/an Either, or an error is signaled. If it is a Just/Right, evaluation proceeds to the next claw. If it is a Nothing/Left, evaluation stops and the value is returned immediately.

After all claws are processed and none yields a Nothing/Left, body … are evaluated.

Macro: maybe-let*-values ( mv-claw … ) body …
Macro: either-let*-values ( mv-claw … ) body …

[SRFI-189]{srfi.189} Multi-value payload version of maybe-let*/either-let*.

Each claw can be either one of the following forms:

identifier

The identifier’s value is taken. It must be a Maybe/an Either, or an error is signaled. If it is a Just/Right, evaluation proceeds to the next claw. If it is a Nothing/Left, evaluation stops and the value is returned immediately.

(formals expression)

The formals is the same as the formals of the lambda form, that is, a proper or dotted list of identifiers.

The expression is evaluated. It must yield a Maybe/an Either, or an error is signaled. If it is a Just/Right, identifiers in the formals are bound with the payload of the Just/Right, and the rest of claws and body are processed with the scope of those identifiers. If it is a Nothing/Left, evaluation stops and the value is returned immediately. An error is signaled if the formals doesn’t match the payload of the Just/Right.

( expression )

The expression is evaluated. It must yield a Maybe/an Either, or an error is signaled. If it is a Just/Right, evaluation proceeds to the next claw. If it is a Nothing/Left, evaluation stops and the value is returned immediately.

After all claws are processed and none yields a Nothing/Left, body … are evaluated.

Macro: either-guard pred body …

[SRFI-189]{srfi.189} The body … is evaluated, and the value(s) it produces are wrapped in a Right and returned. If an exception occurs in body …, the thrown condition is passed to a predicate pred. If the condition satisfies the predicate, it is wrapped in a Left and returned. Otherwise, the condition is reraised with raise-continuable.


11.42.7 Trivalent logic

This section describes procedures that deal with trivalent logic—a value can be a false value (Just #f), a true value (Just with anything other than #f), and Nothing.

If any of the arguments is Nothing, the result becomes Nothing (except tri=?).

All the argument must be Maybe type, or an error is signalled.

Function: tri-not maybe

[SRFI-189]{srfi.189} Returns Just #t if maybe is trivalent-false, Just #f if maybe is triavlent-true, and Nothing if maybe is Nothing.

Function: try=? maybe …

[SRFI-189]{srfi.189} Returns Just #t if arguments are either all trivalent-true or all trivalent-false. Otherwise return Just #f. Note that if any of the argument is Nothing, the result is Just #f (even all arguments are Nothing).

Function: try-and maybe …

[SRFI-189]{srfi.189} Returns Just #t if all arguments are trivalent-true, Just #f if all arguments are Just but at least one of them is Just #f, and Nothing if any of the arguments is Nothing. If there’s no arguments, Just #t is returned.

This is not a shortcut operation like and.

Function: try-or maybe …

[SRFI-189]{srfi.189} Returns Just #f if all arguments are trivalent-false, Just #t if all arguments are Just but at least one of them is trivalent-true, and Nothing if any of the arguments is Nothing. If there’s no arguments, Just #f is returned.

This is not a shortcut operation like or.

Function: try-merge maybe …

[SRFI-189]{srfi.189} If all arguments are Nothing, Nothing is returned. Otherwise, first Just is returned.



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT