Skip to content

Generates F# wrappers for .Net types: provides curryable functions and partial active patterns for simplified interop.

License

Notifications You must be signed in to change notification settings

aaron-comyn/curryup

Repository files navigation

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.

About

Generates F# wrappers for .Net types: provides curryable functions and partial active patterns for simplified interop.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages