F# C# Other
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.paket
src
tests
.gitattributes
.gitignore
FSharpApiSearch.sln
LICENSE.txt
README.md
RELEASE_NOTES.md
build.cmd
build.fsx
build.sh
paket.dependencies
paket.lock

README.md

FSharpApiSearch

F# API Search Engineはシグネチャや名前でF#のAPIを検索できる検索エンジンです。

プロジェクト一覧

プロジェクト名 概要
FSharpApiSearch 検索エンジン本体
FSharpApiSearch.Database 検索エンジンのデータベース作成ツール
FSharpApiSearch.Console 検索エンジンのフロントエンド(コンソールアプリケーション)

導入方法

リリースページからzipファイルをダウンロードし、展開してください。

使い方

まず最初にFSharpApiSearch.Database.exeを実行してデータベースを作成します。

FSharpApiSearch.Database.exe

デフォルトで検索できるアセンブリはFSharp.CoremscorlibSystemSystem.Coreです。 データベース作成時にアセンブリを指定すると検索対象を追加できます。--libオプションでアセンブリを検索するディレクトリを指定できます。 指定するアセンブリが依存するアセンブリも指定して下さい。

FSharpApiSearch.Database.exe --lib:TargetAssemblyDirectory TargetAssembly1 TargetAssembly2 DependentAssembly

FSharpApiSearch.Console.exeにクエリを与えずに実行するとインタラクティブモードで起動します。 インタラクティブモードを終了するには#qを入力してください。

FSharpApiSearch.Console.exe

引数にクエリを渡すと一度だけ検索を行います。

FSharpApiSearch.Console.exe "int -> int"

作成したデータベースを実際に検索で使用するには--targetオプションを使用します。

FSharpApiSearch.Console.exe --target:TargetAssembly1 --target:TargetAssembly2

--targetオプションを使用するとデフォルトのFSharp.CoremscorlibSystemSystem.Coreは検索対象に含まれなくなるため、 検索対象に含めたい場合は明示的に指定します。

FSharpApiSearch.Console.exe --target:TargetAssembly1 --target:TargetAssembly2 --target:FSharp.Core --target:mscorlib --target:System --target:System.Core

検索オプション

respect-name-differenceオプション

respect-name-differenceオプションが有効の場合は、クエリ中の異なる型変数や名前付きワイルドカードの名前の違いを検索に反映します。 異なる名前同士は同じ型にマッチしません。 例えば、?a -> ?aというクエリはint -> intというシグネチャにマッチしますが、?a -> ?bというクエリはint -> intにマッチしません。

このオプションに無効にした場合は、?a -> ?bというクエリでint -> intにマッチします。

greedy-matchingオプション

greedy-matchingオプションが有効の場合は、型変数と他の型がそれぞれマッチするようになり、一致度が高い順に並び替えられて表示されます。 また、検索に型制約が考慮されるようになります。

ignore-param-styleオプション

関数、メソッドの引数の形式には、カリー化形式(arg1 -> arg2 -> returnType)とタプル形式(arg1 * arg2 -> returnType)の2種類があります。 ignore-param-styleオプションが有効の場合は、カリー化形式とタプル形式を無視してマッチします。

ignore-caseオプション

ignore-caseオプションが有効の場合は、API名、型名とのマッチング時に大文字と小文字を区別しません。

substringオプション

substringオプションが有効の場合は、部分文字列で検索します。

swap-orderオプション

swap-orderオプションが有効の場合は、引数とタプルの順番を入れ替えて検索します。 例えば、a -> b -> cというクエリでb -> a -> cにマッチします。

complementオプション

complementオプションが有効の場合は、不足している引数とタプルの要素を補完して検索します。 例えば、a * cというクエリでa * b * cにマッチします。

single-letter-as-variableオプション

single-letter-as-variableオプションが有効の場合は、一文字の型名を型変数名として扱います。 例えば、t listというクエリは't listと同じです。

languageオプション

クエリ、検索、結果表示を、languageオプションで指定したプログラミング言語に切り替えます。 このオプションにはF# とC# を指定できます。

xmldocオプション

xmldocオプションが有効の場合は、検索結果にXMLドキュメントを表示します。

F#のクエリ仕様

F#のクエリは基本的にはF#のシグネチャと同じです。FSharpApiSearchの拡張のみ詳細を説明します。

>はFSharpApiSearch.Console.exeをインタラクティブモードで起動したときのプロンプトです。

検索可能なAPI

API クエリ例
モジュールの関数と値 int -> string
レコード、構造体のフィールド Ref<'a> -> 'a
判別共用体 'a -> Option<'a>
メンバー 'a list -> int
コンストラクター Uri : _
Uri.new : _
Uri..ctor : _
名前 (関数名、メンバー名等) head : 'a list -> 'a
head
アクティブパターン (||) : ... -> Expr -> ?
型、型略称、モジュール List<'T>
コンピュテーション式 { let! } : Async<'T>
サブタイプ検索 #seq<'a> -> 'a

名前検索

名前で検索するにはname : signatureまたはnameと書きます。シグネチャを指定しない場合は、シグネチャ部分に_を指定します。

> id : 'a -> 'a
Microsoft.FSharp.Core.Operators.id: 'T -> 'T, module value, FSharp.Core

> choose
Microsoft.FSharp.Collections.Array.Parallel.choose: ('T -> option<'U>) -> 'T[] -> 'U[], module value, FSharp.Core
Microsoft.FSharp.Collections.Array.choose: ('T -> option<'U>) -> 'T[] -> 'U[], module value, FSharp.Core
Microsoft.FSharp.Collections.List.choose: ('T -> option<'U>) -> list<'T> -> list<'U>, module value, FSharp.Core
Microsoft.FSharp.Collections.Seq.choose: ('T -> option<'U>) -> seq<'T> -> seq<'U>, module value, FSharp.Core
Microsoft.FSharp.Control.Event.choose: ('T -> option<'U>) -> IEvent<'Del, 'T> -> IEvent<'U>, module value, FSharp.Core
  when 'Del : delegate and 'Del :> Delegate
Microsoft.FSharp.Control.Observable.choose: ('T -> option<'U>) -> IObservable<'T> -> IObservable<'U>, module value, FSharp.Core

> choose : _
Microsoft.FSharp.Collections.Array.Parallel.choose: ('T -> option<'U>) -> 'T[] -> 'U[], module value, FSharp.Core
Microsoft.FSharp.Collections.Array.choose: ('T -> option<'U>) -> 'T[] -> 'U[], module value, FSharp.Core
Microsoft.FSharp.Collections.List.choose: ('T -> option<'U>) -> list<'T> -> list<'U>, module value, FSharp.Core
Microsoft.FSharp.Collections.Seq.choose: ('T -> option<'U>) -> seq<'T> -> seq<'U>, module value, FSharp.Core
Microsoft.FSharp.Control.Event.choose: ('T -> option<'U>) -> IEvent<'Del, 'T> -> IEvent<'U>, module value, FSharp.Core
  when 'Del : delegate and 'Del :> Delegate
Microsoft.FSharp.Control.Observable.choose: ('T -> option<'U>) -> IObservable<'T> -> IObservable<'U>, module value, FSharp.Core

アスタリスク(*)を使用すると部分一致検索ができます。 例えば、FSharp.Core.String.* : _FSharp.Core.Stringモジュールの全てのAPIを表示します。

> FSharp.Core.String.* : _
Microsoft.FSharp.Core.String.collect: (char -> string) -> string -> string, module value, FSharp.Core
Microsoft.FSharp.Core.String.concat: string -> seq<string> -> string, module value, FSharp.Core
Microsoft.FSharp.Core.String.exists: (char -> bool) -> string -> bool, module value, FSharp.Core
Microsoft.FSharp.Core.String.filter: (char -> bool) -> string -> string, module value, FSharp.Core
...

ワイルドカード

通常、'aなどの型変数とintなどの型名はマッチしません。 しかし、どちらのケースもまとめて検索したい場合があります。 このような場合に、ワイルドカード?または_が使えます。

> ? -> list<?> -> ?
Microsoft.FSharp.Collections.List.append: list<'T> -> list<'T> -> list<'T>, module value, FSharp.Core
Microsoft.FSharp.Collections.List.averageBy: ('T -> 'U) -> list<'T> -> 'U, module value, FSharp.Core
  when 'U : (static member op_Addition : 'U * 'U -> 'U) and 'U : (static member DivideByInt : 'U * int -> 'U) and 'U : (static member get_Zero : unit -> 'U)
Microsoft.FSharp.Collections.List.choose: ('T -> option<'U>) -> list<'T> -> list<'U>, module value, FSharp.Core
Microsoft.FSharp.Collections.List.chunkBySize: int -> list<'T> -> list<list<'T>>, module value, FSharp.Core
...

また、ワイルドカードに名前を付けることで、同じ名前を持つワイルドカードの位置には同一の型名が入るという条件を追加できます。 例えば、? -> ?は以下のすべての関数にマッチします。

  • 'a -> 'a
  • int -> int
  • 'a -> int
  • int -> string

しかし、?a -> ?aのように名前を付けると、上の例では'a -> intint -> stringにはマッチしなくなります。

サブタイプ検索

サブタイプ検索とは、指定した基本型またはインターフェイスと互換性のある型を指定する制約です。

クエリでサブタイプ検索を使用するには#typeと書きます。typeの部分には型名とインターフェイス名を指定できます。型名に型パラメータ、ワイルドカードは指定できません。

例えば、? -> #seq<'T>seq<'T>を継承したList<'T>IList<'T>'T[]等の型を返す関数を検索できます。

メンバー検索

インスタンスメンバー

インスタンスメンバーを検索するにはreceiver -> signatureと書きます。

メソッドを検索する場合はreceiver -> arg -> returnTypeと書きます。

多引数のメソッドを検索するにはreceiver -> arg1 -> arg2 -> returnTypeまたはreceiver -> arg1 * arg2 -> returnTypeと書きます。 通常ではメソッドの引数がタプル形式(arg1 * arg2)とカリー化形式(arg1 -> arg2)を区別せずに検索します。 引数の形式を区別して検索したい場合はignore-param-styleオプションを無効にします。

プロパティを検索する場合はreceiver -> propertyTypeと書きます。 インデックス付きプロパティはreceiver -> index -> propertyTypeと書きます。

静的メンバー

静的メンバーはモジュール内の値や関数と同じクエリで検索できます。多引数メソッドはインスタンスメソッドと同様にarg1 -> arg2 -> returnTypeまたはarg1 * arg2 -> returnTypeと書きます。

アクティブパターン

アクティブパターンを検索するには(||) : (args ->) inputType -> returnTypeと書きます。 パーシャルアクティブパターンを検索する場合は(|_|) : (args ->) inputType -> returnTypeと書きます。

inputTypeの部分にはアクティブパターンで扱う型を指定します。例えば、Exprに対するアクティブパターンを検索したい場合は(||) : ... -> Expr -> ?と書きます。

argsの部分にはアクティブパターンの引数を指定します。 引数があるアクティブパターンを検索したい場合は(||) : arg1 -> arg2 -> inputType -> returnTypeと書きます。 引数が無いアクティブパターンを検索したい場合は(||) : inputType -> returnTypeと書きます。 引数の有無を区別せず検索する場合は引数部分に...というキーワードを用いて、(||) : ... -> inputType -> returnTypeと書きます。

retyrnTypeの部分にはアクティブパターンの実態である関数が返す型を指定します。 アクティブパターン関数の戻り値は、ケースが1つ、複数、パーシャルアクティブパターンそれぞれで異なります。 対応する任意の型、option<_>Choice<_,...,_>を指定して下さい。 通常はワイルドカード(?)を使うことをお勧めします。

コンピュテーション式

コンピュテーション式を検索するには{ syntax } : typeと書きます。指定した構文と型を扱えるビルダーを検索します。

syntaxにはlet!yieldyield!returnreturn!useuse!if/thenforwhiletry/withtry/finallyと任意のカスタムオペレーション名を指定できます。 syntaxを複数指定する場合は;で区切り、{ s1; s2 } : typeと書きます。

C#のクエリ仕様

C#のクエリは、C#のシグネチャとは文法が異なります。

検索可能なAPI

API クエリ例
メンバー object -> () -> string
string -> int
コンストラクター Uri : _
Uri..ctor : _
型パラメーター List<T> -> int
Dictionary<tkey, tvalue>
<TKey, TValue> : Dictionary<TKey, TValue>
名前 (メンバー名等) Length : string -> int
Length
List
サブタイプ検索 <T> : #IEnumerable<T> -> T

名前検索

メンバーや型を名前で検索するにはname : signatureまたはnameと書きます。シグネチャを指定しない場合は、シグネチャ部分に_を指定します。

> Length : string -> int
System.String.Length : int, instance property with get, mscorlib

> Length
int Array.Length { get; }, instance property, mscorlib
int BitArray.Length { get; set; }, instance property, mscorlib
long BufferedStream.Length { get; }, instance property, mscorlib
long FileInfo.Length { get; }, instance property, mscorlib
...

> Length : _
int Array.Length { get; }, instance property, mscorlib
int BitArray.Length { get; set; }, instance property, mscorlib
long BufferedStream.Length { get; }, instance property, mscorlib
long FileInfo.Length { get; }, instance property, mscorlib
...

アスタリスク(*)を使用すると部分一致検索ができます。 例えば、System.String.* : _System.String型の全てのAPIを表示します。

> System.String.* : _
System.Array.Length : int, instance property with get, mscorlib
System.Collections.BitArray.Length : int, instance property with get set, mscorlib
System.ComponentModel.DataObjectFieldAttribute.Length : int, instance property with get, System
System.ComponentModel.MaskedTextProvider.Length : int, instance property with get, System
...

型パラメーター

型パラメーターの記述は次の3つがあります。

形式 型パラメーター 備考
<t> : signature <TKey, TValue> : Dictionary<TKey, TValue> TKey, TValue 冗長な形式で型パラメーターに大文字を使用できる
全て小文字 Dictionary<tkey, tvalue> tkey, tvalue 全て小文字の場合は<T>の部分を省略できる
一文字 List<T> -> int T 一文字の場合は<T>の部分を省略できる

ただし全て小文字の場合でもintやstring等の組み込み型は型パラメーターとして扱われません。

クエリの型パラメーター名は検索対象の型パラメーター名と一致している必要はありません。 例えば、List<A>というクエリはSystem.Collections.Generics.List<T>型とマッチします。

ワイルドカード

通常、Tなどの型パラメーターとintなどの型名はマッチしません。 しかし、どちらのケースもまとめて検索したい場合があります。 このような場合に、ワイルドカード?が使えます。

> <T> : List<T> -> ? -> int
System.Collections.Generic.List<T>.BinarySearch(T item) : int, instance method, mscorlib
System.Collections.Generic.List<T>.FindIndex(Predicate<T> match) : int, instance method, mscorlib
System.Collections.Generic.List<T>.FindLastIndex(Predicate<T> match) : int, instance method, mscorlib
System.Collections.Generic.List<T>.IndexOf(T item) : int, instance method, mscorlib
...

また、ワイルドカードに名前を付けることで、同じ名前を持つワイルドカードの位置には同一の型名が入るという条件を追加できます。 例えば、? -> ?は以下のすべてにマッチします。

  • static T F1<T>(T x)
  • static int F2 (int x)
  • static T F3<T>(int x)
  • static int F4 (string x)

しかし、?a -> ?aのように名前を付けると、上の例ではF2F4にはマッチしなくなります。

サブタイプ検索

サブタイプ検索とは、指定した基本型またはインターフェイスと互換性のある型を指定する制約です。

クエリでサブタイプ検索を使用するには#typeと書きます。typeの部分には型名とインターフェイス名を指定できます。型名に型パラメータ、ワイルドカードは指定できません。

例えば、<T> : ? -> #IEnumerable<T>IEnumerable<T>を継承したList<T>IList<T>T[]等の型を返すメソッドを検索できます。

メンバー検索

インスタンスメンバー

メソッドを検索する場合はreceiver -> (arg) -> returnTypeと書きます。 多引数のメソッドはreceiver -> (arg1, arg2) -> returnTypeと書きます。 引数部分の括弧は省略できます。引数または戻り値が無いAPIを検索したい場合は()voidを使用します。

> <T> : List<T> -> T -> int
System.Collections.Generic.List<T>.BinarySearch(T item) : int, instance method, mscorlib
System.Collections.Generic.List<T>.IndexOf(T item) : int, instance method, mscorlib
...

プロパティを検索する場合はreceiver -> propertyTypeと書きます。 インデックス付きプロパティはreceiver -> index -> propertyTypeと書きます。

> <T> : List<T> -> int
System.Collections.Generic.List<T>.Capacity : int, instance property with get set, mscorlib
System.Collections.Generic.List<T>.Count : int, instance property with get, mscorlib
...

静的メンバー

メソッドを検索する場合は(arg) -> returnTypeと書きます。 プロパティを検索する場合はpropertyTypeと書きます。

> string -> int
System.Convert.ToInt32(string value) : int, static method, mscorlib
System.Int32.Parse(string s) : int, static method, mscorlib
...

このように、メンバーが属する型は静的メンバーのクエリには記述しません。

FSharp.Compiler.Service の制限により対応できないAPI

  • C#で定義されたクラス、構造体のフィールド

動作環境

  • .Net Framework 4.5
  • F# 4.1

使用ライブラリ