Skip to content

Latest commit

 

History

History
135 lines (91 loc) · 3.85 KB

README.md

File metadata and controls

135 lines (91 loc) · 3.85 KB

CurryUp

Generates curryable functional wrappers for .Net types. This allows for function transformations and partial application of calls to standard libraries and in interop scenarios. The wrappers provide common access to instance and static methods, and partial active patterns for boolean properties.

Sleek, happy, pipeable F# functions to wrap existing .Net library code.

	"piping" |> stringBuilder |> appendLine' "is" |> appendLine' "easy!" 

instead of

	let sb = stringBuilder "tupled args"
	sb.AppendLine("are more")
	sb.AppendLine("verbose")

Usage

Save-link-as curryup.fsx and load it from an F# script:

	#load "curryup.fsx"
	open CurryUp

	Curry.up "filenameOrIgnoredString" "namespaceOrTypeOrLibrary"

A new F# script will be generated for inclusion in your project (or its contents written to FSI).

	Curry.up "myint.fsx"  "System.Int32"
	Curry.up "generic.fs" "System.Collections.Generic"
	Curry.up "custom.fsx" "C:\\proj\\lib\\my.dll"
	Curry.up ""	          "System.Text.StringBuilder"

By default CurryUp will place curried namespaces in a "*.Curried" sub-namespace.
Method overloads are generated by back-ticking successive method names.

Examples

CurryUp generates curryable wrappers for standard .Net types allowing consistent access patterns across an objects members. Example.fsx shows various generation patterns.

Wrapper Functions
	open System.Collections.Generic.Curried.Stack

	new Stack<string> (["1";"2"])
	|> push "3"
	|> push "4"
	|> push "5"
	|> push "6"
	|> pop
Module Aliasing
	module s = System.Collections.Generic.Curried.Stack

	new Stack<string> (["one" ; "two"])
	|> s.push "three" 
	|> s.push "four" 
	|> s.push "five" 
	|> s.peek 
Full Wrapper
	open System.Collections.Generic.Curried

	new Dictionary<string,string> 1
	|> Dictionary.add "k1" "v1"
	|> Dictionary.add "k2" "v2"
	|> Dictionary.add "k3" "v3"
	|> Dictionary.add "k4" "v4"
	|> Dictionary.ContainsKey "k2"

Method and Namespace Overloading

By default, as specified by its Curry.DefaultConfiguration, the script will overload methods by adding a back tick and generate all code in a unique .Curried namespace.

The names will be created by processing two functions on a config record that can be passed to the script.

Customization and Generation Examples

CurryUp will load types from namespaces, libraries, or individual types. Output will either be to stdout, or to an fsharp source file at the path provided.

From an F# script:

	#load "curryup.fsx"
	open CurryUp

	// standard

	Curry.up "myfile.fs"  "System.Math"
	Curry.up "myfile.fsx" "System.Collections.Generic"

	let outfile = (__SOURCE_DIRECTORY__ + "/test.fsx")
	@"System.Collections.Generic"        |> Curry.up outfile     // whole namespace
	@"System.Collections.Generic.List`1" |> Curry.up outfile     // individual type
	@"/proj/src/bin/release/my.dll"      |> Curry.up outfile     // all types in library


	// full configuration and generation customization

	let config = 
		{ Curry.DefaultConfig with 
			  From = "System.Collections.Generic"
			  To   = "test.fsx"
			  NameOverload     = fun name -> name + "'"
			  CurriedNamespace = fun namespace' -> namespace' + ".Curried" }
	Curry.up' config

Status

The code generation is not 100%: generic constraints are effectively ignored, and some corner cases with references and native pointers still abound. Manual correction of the generated code should be used as a stop-gap.

License

The library is available under Apache 2.0. For more information see the License file in the GitHub repository.