F# API Search Engine is a search engine that allows you to search for F# APIs by signature or name.
project name | overview |
---|---|
FSharpApiSearch | Search engine body |
FSharpApiSearch.Database | Search engine database creation tool |
FSharpApiSearch.Console | Search engine front end (console application) |
Download the zip file from the release page and extract it.
First, run FSharpApiSearch.Database.exe to create a database.
FSharpApiSearch.Database.exe
The assemblies that can be searched by default are FSharp.Core
, mscorlib
, System
, and System.Core
. You can add search targets by specifying an assembly when creating a database. You can specify the directory to search for assemblies with the --lib
option. Please also specify the assemblies on which the specified assembly depends.
FSharpApiSearch.Database.exe --lib:TargetAssemblyDirectory TargetAssembly1 TargetAssembly2 DependentAssembly
If you run FSharpApiSearch.Console.exe without giving it a query, it will start in interactive mode. Type #q
to exit interactive mode.
FSharpApiSearch.Console.exe
If you pass a query as an argument, the search will be performed only once.
FSharpApiSearch.Console.exe "int -> int"
Use --target
option to actually use the created database for searching.
FSharpApiSearch.Console.exe --target:TargetAssembly1 --target:TargetAssembly2
If you use --target
option, the default FSharp.Core
, mscorlib
, System
, and System.Core
will not be included in the search target, so if you want to include them in the search target, specify them explicitly.
FSharpApiSearch.Console.exe --target:TargetAssembly1 --target:TargetAssembly2 --target:FSharp.Core --target:mscorlib --target:System --target:System.Core
respect-name-difference
option If respect-name-difference
option is enabled, the search respects differences in the names of different type variables and named wildcards in the query. Different names do not match the same type. For example, the query ?a -> ?a
matches the signature int -> int
, but the query ?a -> ?b
does not match int -> int
.
If this option is disabled, the query ?a -> ?b
will match int -> int
.
greedy-matching
option If the greedy-matching
option is enabled, type variables and other types will be matched individually, and the results will be sorted and displayed in descending order of match. Also, type constraints are now taken into account in searches.
ignore-param-style
option There are two types of argument formats for functions and methods: curried format ( arg1 -> arg2 -> returnType
) and tuple format ( arg1 * arg2 -> returnType
). If ignore-param-style
option is enabled, the match ignores curried and tuple formats.
ignore-case
option If the ignore-case
option is enabled, case is ignored when matching API names and type names.
substring
option If substring
option is enabled, searches by substring.
swap-order
option If swap-order
option is enabled, the search will swap the order of the arguments and tuples. For example, the query a -> b -> c
matches b -> a -> c
.
complement
option If complement
option is enabled, completes and searches for missing arguments and tuple elements. For example, the query a * c
matches a * b * c
.
single-letter-as-variable
option If single-letter-as-variable
option is enabled, single-letter type names are treated as type variable names. For example, the query t list
is the same as 't list
.
language
option Switches queries, searches, and result display to the programming language specified by language
option. This option accepts F# and C#.
xmldoc
options If xmldoc
option is enabled, displays XML documents in search results.
F# queries are basically the same as F# signatures. Only the extension of FSharpApiSearch will be explained in detail.
>
is the prompt when you start FSharpApiSearch.Console.exe in interactive mode.
API | Query example |
---|---|
Module functions and values | int -> string |
record, structure field | Ref<'a> -> 'a |
discriminated union | 'a -> Option<'a> |
member | 'a list -> int |
constructor | Uri : _ Uri.new : _ Uri..ctor : _ |
Name (function name, member name, etc.) | head : 'a list -> 'a head |
active pattern | (||) : ... -> Expr -> ? |
Types, type abbreviations, modules | List<'T> |
calculation expression | { let! } : Async<'T> |
Subtype search | #seq<'a> -> 'a |
To search by name, write name : signature
or name
. If you do not specify a signature, specify _
in the signature part.
> 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
Use the asterisk ( *
) to search for partial matches. For example, FSharp.Core.String.* : _
displays all APIs of the FSharp.Core.String
module.
> 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
...
Normally, type variables such as 'a
and type names such as int
do not match. However, you may want to search for both cases at once. In such cases, you can use the wildcard ?
or _
.
> ? -> 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
...
Also, by naming wildcards, you can add a condition that the same type name will appear in the wildcard positions with the same name. For example, ? -> ?
matches all of the following functions:
'a -> 'a
int -> int
'a -> int
int -> string
However, if you name it like ?a -> ?a
, the example above will not match 'a -> int
or int -> string
.
A subtype search is a constraint that specifies types that are compatible with a specified base type or interface.
To use subtype search in a query, write #type
. You can specify the type name and interface name in type
part. Type parameters and wildcards cannot be specified in the type name.
For example, ? -> #seq<'T>
can search for functions that inherit from seq<'T>
return types such as List<'T>
, IList<'T>
, and 'T[]
.
To search for instance members, write receiver -> signature
.
When searching for a method, write receiver -> arg -> returnType
.
To search for multi-argument methods, write receiver -> arg1 -> arg2 -> returnType
or receiver -> arg1 * arg2 -> returnType
. Normally, method arguments are searched in tuple format ( arg1 * arg2
) and curried format ( arg1 -> arg2
) without distinguishing between them. If you want to search by argument format, disable ignore-param-style
option.
To search for a property, write receiver -> propertyType
. Indexed properties are written as receiver -> index -> propertyType
.
Static members can be searched with the same queries as values and functions in modules. Multi-argument methods are written like instance methods arg1 -> arg2 -> returnType
or arg1 * arg2 -> returnType
.
To search for an active pattern, write (||) : (args ->) inputType -> returnType
. To search for a partially active pattern, write (|_|) : (args ->) inputType -> returnType
.
In inputType
part, specify the type handled by the active pattern. For example, if you want to search for active patterns for Expr
write (||) : ... -> Expr -> ?
Specify the active pattern arguments in args
part. If you want to search for active patterns with arguments, write (||) : arg1 -> arg2 -> inputType -> returnType
. If you want to search for active patterns with no arguments, write (||) : inputType -> returnType
. If you want to search without distinguishing between the presence or absence of arguments, use the keyword ...
in the argument part and write (||) : ... -> inputType -> returnType
.
The retyrnType
part specifies the type returned by the function, which is the actual active pattern. The return value of the active pattern function is different for single, multiple, and partially active patterns. Please specify any corresponding type, option<_>
, Choice<_,...,_>
. It is generally recommended to use wildcards ( ?
).
To search for a computation expression, write { syntax } : type
. Finds a builder that can handle the specified syntax and type.
syntax
can include let!
, yield
, yield!
, return
, return!
, use
, use!
, if/then
, for
, while
, try/with
, try/finally
and any custom operation name. If you want to specify multiple syntax
, separate them with ;
and write { s1; s2 } : type
.
C# queries have different syntax than C# signatures.
API | Query example |
---|---|
member | object -> () -> string string -> int |
constructor | Uri : _ Uri..ctor : _ |
type parameter | List<T> -> int Dictionary<tkey, tvalue> <TKey, TValue> : Dictionary<TKey, TValue> |
Name (member name, etc.) | Length : string -> int Length |
mold | List |
Subtype search | <T> : #IEnumerable<T> -> T |
To search for a member or type by name, write name : signature
or name
. If you do not specify a signature, specify _
in the signature part.
> 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
...
Use the asterisk ( *
) to search for partial matches. For example, System.String.* : _
displays all APIs of type System.String
.
> 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
...
There are three types of type parameter descriptions:
format | example | type parameter | remarks |
---|---|---|---|
<t> : signature | <TKey, TValue> : Dictionary<TKey, TValue> | TKey , TValue | Uppercase letters can be used in type parameters in a verbose form |
all lower case | Dictionary<tkey, tvalue> | tkey , tvalue | If all letters are lowercase, you can omit the <T> part. |
one character | List<T> -> int | T | If it is a single character, the <T> part can be omitted. |
However, even if they are all lowercase, built-in types such as int and string are not treated as type parameters.
The type parameter name in the query does not have to match the type parameter name being searched. For example, the query List<A>
matches the type System.Collections.Generics.List<T>
.
Normally, type parameters such as T
and type names such as int
do not match. However, you may want to search for both cases at once. In such cases, you can use ?
.
> <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
...
Also, by naming wildcards, you can add a condition that the same type name will appear in the wildcard positions with the same name. For example, ? -> ?
matches all of the following:
static T F1<T>(T x)
static int F2 (int x)
static T F3<T>(int x)
static int F4 (string x)
However, if you name it like ?a -> ?a
, the example above will not match F2
or F4
.
A subtype search is a constraint that specifies types that are compatible with a specified base type or interface.
To use subtype search in a query, write #type
. You can specify the type name and interface name in type
part. Type parameters and wildcards cannot be specified in the type name.
For example, <T> : ? -> #IEnumerable<T>
can search for methods that inherit from IEnumerable<T>
and return types such as List<T>
, IList<T>
, and T[]
.
To search for a method, write receiver -> (arg) -> returnType
. Multi-argument methods are written as receiver -> (arg1, arg2) -> returnType
. The parentheses in the argument part can be omitted. If you want to search for APIs that have no arguments or return values, use ()
and 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
...
To search for a property, write receiver -> propertyType
. Indexed properties are written as 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
...
To search for a method, write (arg) -> returnType
. When searching for a property, write propertyType
.
> string -> int
System.Convert.ToInt32(string value) : int, static method, mscorlib
System.Int32.Parse(string s) : int, static method, mscorlib
...
In this way, the type to which the member belongs is not stated in the static member query.