I've been blogging lately about functors in F#, in order to explain applicative functors, all so I could explain formlets now. Formlets are an abstraction of HTML forms. Formlets are composable, reusable, type-safe (as much as the host language is type-safe anyway) and extensible. And they are described, of course, in terms of applicative functors.
The concept of formlets was originally developed by Ezra Cooper, Sam Lindley, Philip Wadler, and Jeremy Yallop, as part of their research for Links, a new programming language oriented to web applications.
Since its introduction in 2008, formlets proved to be a very popular concept, being ported to Haskell, Scheme (Racket), Common Lisp (Hunchentoot), Scala and JavaScript.
If you regularly read the news about F# you probably know about WebSharper, a cool web framework for F#, which has formlets as one of its many features. Being a commercial product, WebSharper has great documentation on how to use formlets, but they only briefly mention the underlying concepts on how they work.
Let's see a sample formlet in an ASP.NET MVC application:
open System open System.Web open System.Web.Mvc open System.Collections.Generic [<HandleError>] type HomeController() = inherit Controller() let inputInt = lift int input let inputDate = puree (fun month day year -> DateTime(year,month,day)) <*> text "Month: " *> inputInt <*> text "Day: " *> inputInt <*> text "Year: " *> inputInt let formlet = puree (fun name order ship amount -> name,order,ship,amount) <*> text "Name: " *> input <* br <*> text "Order date: " *> inputDate <* br <*> text "Shipping date: " *> inputDate <* br <*> text "Qty: " *> inputInt <* br member x.Index() = x.ViewData.["Message"] <- "Welcome to ASP.NET MVC!" x.View(box <| render formlet) :> ActionResult member x.Register() = let env = fromNV x.Request.Form let name,orderDate,shippingDate,amount = run formlet env x.ViewData.["Name"] <- name x.ViewData.["Ordered"] <- orderDate x.ViewData.["Shipping"] <- shippingDate x.ViewData.["Amount"] <- amount x.View() :> ActionResult F# Web Snippets
Index.aspx:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Home Page </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2><%: ViewData["Message"] %></h2> <p> <% using (Html.BeginForm("Register", "Home")) { %> <%= Model%> <input type="submit" value="Submit" /> <% } %> </p> </asp:Content>
Register.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Register </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <%: ViewData["Ordered"] %>: <%: ViewData["Name"] %> has requested <%: ViewData["Amount"] %> items to be delivered on <%: ViewData["Shipping"] %> </asp:Content>
You can hover over any value on the F# snippets in this post and get a tooltip with types, thanks to F# Web Snippets.
If you read my previous articles on applicative functors you'll recognize the standard operations pure (or puree), <*>
and lift.
Note how the final formlet is composed from more basic formlets: one that models date input, which in turn uses an formlet to input integers. They all rely on a primitive input formlet (of type string Formlet
) that models an <input type="text"/>
.
Also note that we didn't define the name
attribute for any input; formlets generate them automatically and also match them when handling submitted values. Running the app shows a form like this:
First thing that should spring to your mind when seeing this is "boy, this is ugly", otherwise I'm not doing my job right :)
Let's see now, step by step, how formlets can be implemented. We start by defining the types. First, a simple model of XML to represent HTML:
type xml_item = | Text of string | Tag of string * (string*string) list * xml_item list // name * attributes * children
We define an environment that will hold key-value pairs from submitted forms:
type Env = (string*string) list
And finally, the Formlet type:
type 'a Formlet = int -> (xml_item list * (Env -> 'a) * int)
Type signatures carry a lot of information, so let's take a moment to read this. It's a function that takes an int and returns a tuple of stuff. We'll see that the int it takes is used to generate the form element name
. The tuple of stuff returned contains: an XML forest (representing HTML), a function we'll call collector, and an int that will be used to generate the next form element name. The collector is used to lookup the submitted value from the environment.
A formlet is an applicative functor, so let's define puree:
[<AutoOpen>] module Formlet = let puree (v: 'a) : 'a Formlet = fun i -> [], (fun _ -> v), i
It's an empty XML, a constant collector, and the same input i. Here's the definition of <*> :
let (<*>) (f: ('a -> 'b) Formlet) (a: 'a Formlet) : 'b Formlet = fun i -> let x1,g,i = f i let x2,q,i = a i x1 @ x2, (fun env -> g env (q env)), i
Step by step: we apply f, since it holds an 'a -> 'b, the collector g collects a function 'a -> 'b. Then we apply a. We return the concatenation of XML forests, the composition of collectors, and the final name seed.
Now some standard functions for applicative functors:
let lift f a = puree f <*> a let lift2 f a b : _ Formlet = puree f <*> a <*> b let ( *>) f a : _ Formlet = lift2 (fun _ z -> z) f a let ( <*) f a : _ Formlet = lift2 (fun z _ -> z) f a
A couple of functions to lift pure markup and text:
let xml (x: xml_item list) : unit Formlet = fun i -> x, (fun _ -> ()), i let text (t: string) : unit Formlet = xml [Text t]
The tag function creates a tag that wraps a formlet:
let tag (name: string) (attr: (string*string) list) (f: 'a Formlet) : 'a Formlet = fun i -> let xml,env,i = f i [Tag(name, attr, xml)],env,i
nextName is responsible for generating form element names:
let nextName = fun i -> "input_" + i.ToString(), i+1
Note that it returns an incremented counter, to be used in the following name.
The input primitive:
let input : string Formlet = fun i -> let name,i = nextName i let collector = List.find (fun (k,_) -> k = name) >> snd let tag = Tag("input", ["name",name], []) [tag], collector, i
The input formlet shows how everything fits together. It generates a fresh name to be used both in the collector and the input tag. This is what keeps the rendered form element and its respective collected value in sync.
Here's a simple <br/> for formatting:
let br: unit Formlet = xml [Tag("br",[],[])]
The run function gets the collector of a formlet, which in turn will produce the collected value when applied to the environment:
let run (f: 'a Formlet) : Env -> 'a = let _,e,_ = f 0 e
That zero is the seed for form element names.
We render a formlet by mapping it to a System.Xml.Linq.XDocument:
open System.Xml.Linq let render (f: 'a Formlet) : XDocument = let xml,_,_ = f 0 let (!!) t = XName.op_Implicit t let xtext (s: string) = XText s :> XObject let xattr (name, value) = XAttribute(!!name, value) :> XObject let xattrs attr = List.map xattr attr let xelem name attr children = XElement(!!name, attr @ children) :> XObject let rec renderForest x = let render' = function | Text t -> xtext t | Tag(name, attr, children) -> xelem name (xattrs attr) (renderForest children) List.map render' x let root = xelem "div" [] (renderForest xml) XDocument root
A helper function to make an Env from a NameValueCollection (such as Request.Form):
open System.Collections.Specialized let fromNV (a: NameValueCollection) = a.AllKeys |> Seq.collect (fun k -> a.GetValues k |> Seq.map (fun v -> k,v)) |> Seq.toList
Even though this was a bare bones implementation of formlets, I hope it served to illustrate how they work. This implementation was taken almost verbatim from the paper The Essence of Form Abstraction [PDF] by the original developers of Formlets mentioned at the beginning of this article. I kept it as simple and clear as possible, with many type annotations that weren't really necessary and intentionally cutting out features.
Next, we'll see how formlets can be factored to a composition of primitive applicatives.
Read this article in Serbo-Croatian (translated by Anja Skrba from Webhostinggeeks.com)
val string : 'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable<string>
implements: seq<char>
implements: System.Collections.IEnumerable
implements: System.IEquatable<string>
Full name: Microsoft.FSharp.Collections.list<_>
type: 'T list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<'T>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<'T>
implements: System.Collections.IEnumerable
| Text of string
| Tag of string * (string * string) list * xml_item list
Full name: Formlets.xml_item
type: xml_item
implements: System.IEquatable<xml_item>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<xml_item>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
Full name: Formlets.Env
type: Env
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<string * string>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<string * string>
implements: System.Collections.IEnumerable
Full name: Formlets.Formlet<_>
val int : 'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
type: int<'Measure>
implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
implements: System.IComparable<int<'Measure>>
implements: System.IEquatable<int<'Measure>>
inherits: System.ValueType
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
type: int
implements: System.IComparable
implements: System.IFormattable
implements: System.IConvertible
implements: System.IComparable<int>
implements: System.IEquatable<int>
inherits: System.ValueType
class
inherit System.Attribute
new : unit -> AutoOpenAttribute
new : path:string -> AutoOpenAttribute
member Path : string
end
Full name: Microsoft.FSharp.Core.AutoOpenAttribute
type: AutoOpenAttribute
implements: System.Runtime.InteropServices._Attribute
inherits: System.Attribute
Full name: Formlets.Formlet.puree
type: int
implements: System.IComparable
implements: System.IFormattable
implements: System.IConvertible
implements: System.IComparable<int>
implements: System.IEquatable<int>
inherits: System.ValueType
type: xml_item list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<xml_item>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<xml_item>
implements: System.Collections.IEnumerable
type: xml_item list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<xml_item>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<xml_item>
implements: System.Collections.IEnumerable
type: Env
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<string * string>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<string * string>
implements: System.Collections.IEnumerable
Full name: Formlets.Formlet.lift
Full name: Formlets.Formlet.lift2
Full name: Formlets.Formlet.xml
type: xml_item list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<xml_item>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<xml_item>
implements: System.Collections.IEnumerable
Full name: Microsoft.FSharp.Core.unit
type: unit
implements: System.IComparable
Full name: Formlets.Formlet.text
type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable<string>
implements: seq<char>
implements: System.Collections.IEnumerable
implements: System.IEquatable<string>
Full name: Formlets.Formlet.tag
type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable<string>
implements: seq<char>
implements: System.Collections.IEnumerable
implements: System.IEquatable<string>
type: (string * string) list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<string * string>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<string * string>
implements: System.Collections.IEnumerable
type: xml_item list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<xml_item>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<xml_item>
implements: System.Collections.IEnumerable
Full name: Formlets.Formlet.nextName
System.Object.ToString() : string
System.Int32.ToString(provider: System.IFormatProvider) : string
System.Int32.ToString(format: string) : string
System.Int32.ToString(format: string, provider: System.IFormatProvider) : string
Full name: Formlets.Formlet.input
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of 'T * 'T list
with
interface System.Collections.IEnumerable
interface System.Collections.Generic.IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
end
Full name: Microsoft.FSharp.Collections.List<_>
type: List<'T>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<'T>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<'T>
implements: System.Collections.IEnumerable
Full name: Microsoft.FSharp.Collections.List.find
type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable<string>
implements: seq<char>
implements: System.Collections.IEnumerable
implements: System.IEquatable<string>
Full name: Microsoft.FSharp.Core.Operators.snd
type: xml_item
implements: System.IEquatable<xml_item>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<xml_item>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
Full name: Formlets.Formlet.br
Full name: Formlets.Formlet.run
Full name: Formlets.Formlet.render
class
inherit System.Xml.Linq.XContainer
new : unit -> System.Xml.Linq.XDocument
new : obj [] -> System.Xml.Linq.XDocument
new : System.Xml.Linq.XDeclaration * obj [] -> System.Xml.Linq.XDocument
new : System.Xml.Linq.XDocument -> System.Xml.Linq.XDocument
member Declaration : System.Xml.Linq.XDeclaration with get, set
member DocumentType : System.Xml.Linq.XDocumentType
member NodeType : System.Xml.XmlNodeType
member Root : System.Xml.Linq.XElement
member Save : string -> unit
member Save : System.IO.TextWriter -> unit
member Save : System.Xml.XmlWriter -> unit
member Save : string * System.Xml.Linq.SaveOptions -> unit
member Save : System.IO.TextWriter * System.Xml.Linq.SaveOptions -> unit
member WriteTo : System.Xml.XmlWriter -> unit
static member Load : string -> System.Xml.Linq.XDocument
static member Load : System.IO.TextReader -> System.Xml.Linq.XDocument
static member Load : System.Xml.XmlReader -> System.Xml.Linq.XDocument
static member Load : string * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XDocument
static member Load : System.IO.TextReader * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XDocument
static member Load : System.Xml.XmlReader * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XDocument
static member Parse : string -> System.Xml.Linq.XDocument
static member Parse : string * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XDocument
end
Full name: System.Xml.Linq.XDocument
type: XDocument
implements: System.Xml.IXmlLineInfo
inherits: XContainer
inherits: XNode
inherits: XObject
class
member Equals : obj -> bool
member GetHashCode : unit -> int
member LocalName : string
member Namespace : System.Xml.Linq.XNamespace
member NamespaceName : string
member ToString : unit -> string
static member Get : string -> System.Xml.Linq.XName
static member Get : string * string -> System.Xml.Linq.XName
end
Full name: System.Xml.Linq.XName
type: XName
implements: System.IEquatable<XName>
implements: System.Runtime.Serialization.ISerializable
type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable<string>
implements: seq<char>
implements: System.Collections.IEnumerable
implements: System.IEquatable<string>
class
inherit System.Xml.Linq.XNode
new : string -> System.Xml.Linq.XText
new : System.Xml.Linq.XText -> System.Xml.Linq.XText
member NodeType : System.Xml.XmlNodeType
member Value : string with get, set
member WriteTo : System.Xml.XmlWriter -> unit
end
Full name: System.Xml.Linq.XText
type: XText
implements: System.Xml.IXmlLineInfo
inherits: XNode
inherits: XObject
class
member AddAnnotation : obj -> unit
member Annotation<'T> : unit -> 'T
member Annotation : System.Type -> obj
member Annotations<'T> : unit -> System.Collections.Generic.IEnumerable<'T>
member Annotations : System.Type -> System.Collections.Generic.IEnumerable<obj>
member BaseUri : string
member Document : System.Xml.Linq.XDocument
member NodeType : System.Xml.XmlNodeType
member Parent : System.Xml.Linq.XElement
member RemoveAnnotations<'T> : unit -> unit
member RemoveAnnotations : System.Type -> unit
end
Full name: System.Xml.Linq.XObject
type: XObject
implements: System.Xml.IXmlLineInfo
class
inherit System.Xml.Linq.XObject
new : System.Xml.Linq.XName * obj -> System.Xml.Linq.XAttribute
new : System.Xml.Linq.XAttribute -> System.Xml.Linq.XAttribute
member IsNamespaceDeclaration : bool
member Name : System.Xml.Linq.XName
member NextAttribute : System.Xml.Linq.XAttribute
member NodeType : System.Xml.XmlNodeType
member PreviousAttribute : System.Xml.Linq.XAttribute
member Remove : unit -> unit
member SetValue : obj -> unit
member ToString : unit -> string
member Value : string with get, set
static member EmptySequence : System.Collections.Generic.IEnumerable<System.Xml.Linq.XAttribute>
end
Full name: System.Xml.Linq.XAttribute
type: XAttribute
implements: System.Xml.IXmlLineInfo
inherits: XObject
type: (string * 'b) list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<string * 'b>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<string * 'b>
implements: System.Collections.IEnumerable
Full name: Microsoft.FSharp.Collections.List.map
type: 'b list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<'b>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<'b>
implements: System.Collections.IEnumerable
type: 'b list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<'b>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<'b>
implements: System.Collections.IEnumerable
class
inherit System.Xml.Linq.XContainer
new : System.Xml.Linq.XName -> System.Xml.Linq.XElement
new : System.Xml.Linq.XName * obj -> System.Xml.Linq.XElement
new : System.Xml.Linq.XName * obj [] -> System.Xml.Linq.XElement
new : System.Xml.Linq.XElement -> System.Xml.Linq.XElement
new : System.Xml.Linq.XStreamingElement -> System.Xml.Linq.XElement
member AncestorsAndSelf : unit -> System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>
member AncestorsAndSelf : System.Xml.Linq.XName -> System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>
member Attribute : System.Xml.Linq.XName -> System.Xml.Linq.XAttribute
member Attributes : unit -> System.Collections.Generic.IEnumerable<System.Xml.Linq.XAttribute>
member Attributes : System.Xml.Linq.XName -> System.Collections.Generic.IEnumerable<System.Xml.Linq.XAttribute>
member DescendantNodesAndSelf : unit -> System.Collections.Generic.IEnumerable<System.Xml.Linq.XNode>
member DescendantsAndSelf : unit -> System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>
member DescendantsAndSelf : System.Xml.Linq.XName -> System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>
member FirstAttribute : System.Xml.Linq.XAttribute
member GetDefaultNamespace : unit -> System.Xml.Linq.XNamespace
member GetNamespaceOfPrefix : string -> System.Xml.Linq.XNamespace
member GetPrefixOfNamespace : System.Xml.Linq.XNamespace -> string
member HasAttributes : bool
member HasElements : bool
member IsEmpty : bool
member LastAttribute : System.Xml.Linq.XAttribute
member Name : System.Xml.Linq.XName with get, set
member NodeType : System.Xml.XmlNodeType
member RemoveAll : unit -> unit
member RemoveAttributes : unit -> unit
member ReplaceAll : obj -> unit
member ReplaceAll : obj [] -> unit
member ReplaceAttributes : obj -> unit
member ReplaceAttributes : obj [] -> unit
member Save : string -> unit
member Save : System.IO.TextWriter -> unit
member Save : System.Xml.XmlWriter -> unit
member Save : string * System.Xml.Linq.SaveOptions -> unit
member Save : System.IO.TextWriter * System.Xml.Linq.SaveOptions -> unit
member SetAttributeValue : System.Xml.Linq.XName * obj -> unit
member SetElementValue : System.Xml.Linq.XName * obj -> unit
member SetValue : obj -> unit
member Value : string with get, set
member WriteTo : System.Xml.XmlWriter -> unit
static member EmptySequence : System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>
static member Load : string -> System.Xml.Linq.XElement
static member Load : System.IO.TextReader -> System.Xml.Linq.XElement
static member Load : System.Xml.XmlReader -> System.Xml.Linq.XElement
static member Load : string * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XElement
static member Load : System.IO.TextReader * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XElement
static member Load : System.Xml.XmlReader * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XElement
static member Parse : string -> System.Xml.Linq.XElement
static member Parse : string * System.Xml.Linq.LoadOptions -> System.Xml.Linq.XElement
end
Full name: System.Xml.Linq.XElement
type: XElement
implements: System.Xml.IXmlLineInfo
implements: System.Xml.Serialization.IXmlSerializable
inherits: XContainer
inherits: XNode
inherits: XObject
type: xml_item list
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<List<xml_item>>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
implements: System.Collections.Generic.IEnumerable<xml_item>
implements: System.Collections.IEnumerable
type: XObject
implements: System.Xml.IXmlLineInfo
Full name: Formlets.Formlet.fromNV
type: NameValueCollection
implements: System.Collections.ICollection
implements: System.Collections.IEnumerable
implements: System.Runtime.Serialization.ISerializable
implements: System.Runtime.Serialization.IDeserializationCallback
inherits: NameObjectCollectionBase
class
inherit System.Collections.Specialized.NameObjectCollectionBase
new : unit -> System.Collections.Specialized.NameValueCollection
new : System.Collections.Specialized.NameValueCollection -> System.Collections.Specialized.NameValueCollection
new : System.Collections.IHashCodeProvider * System.Collections.IComparer -> System.Collections.Specialized.NameValueCollection
new : int -> System.Collections.Specialized.NameValueCollection
new : System.Collections.IEqualityComparer -> System.Collections.Specialized.NameValueCollection
new : int * System.Collections.IEqualityComparer -> System.Collections.Specialized.NameValueCollection
new : int * System.Collections.Specialized.NameValueCollection -> System.Collections.Specialized.NameValueCollection
new : int * System.Collections.IHashCodeProvider * System.Collections.IComparer -> System.Collections.Specialized.NameValueCollection
member Add : System.Collections.Specialized.NameValueCollection -> unit
member Add : string * string -> unit
member AllKeys : string []
member Clear : unit -> unit
member CopyTo : System.Array * int -> unit
member Get : string -> string
member Get : int -> string
member GetKey : int -> string
member GetValues : string -> string []
member GetValues : int -> string []
member HasKeys : unit -> bool
member Item : string -> string with get, set
member Item : int -> string
member Remove : string -> unit
member Set : string * string -> unit
end
Full name: System.Collections.Specialized.NameValueCollection
type: NameValueCollection
implements: System.Collections.ICollection
implements: System.Collections.IEnumerable
implements: System.Runtime.Serialization.ISerializable
implements: System.Runtime.Serialization.IDeserializationCallback
inherits: NameObjectCollectionBase
from Microsoft.FSharp.Collections
Full name: Microsoft.FSharp.Collections.Seq.collect
NameValueCollection.GetValues(index: int) : string []
NameValueCollection.GetValues(name: string) : string []
Full name: Microsoft.FSharp.Collections.Seq.map
type: string
implements: System.IComparable
implements: System.ICloneable
implements: System.IConvertible
implements: System.IComparable<string>
implements: seq<char>
implements: System.Collections.IEnumerable
implements: System.IEquatable<string>
Full name: Microsoft.FSharp.Collections.Seq.toList
class
inherit System.Web.Mvc.FilterAttribute
new : unit -> System.Web.Mvc.HandleErrorAttribute
member ExceptionType : System.Type with get, set
member Master : string with get, set
member OnException : System.Web.Mvc.ExceptionContext -> unit
member View : string with get, set
end
Full name: System.Web.Mvc.HandleErrorAttribute
type: HandleErrorAttribute
implements: Runtime.InteropServices._Attribute
implements: IExceptionFilter
inherits: FilterAttribute
inherits: Attribute
class
inherit Controller
new : unit -> HomeController
member Index : unit -> ActionResult
member Register : unit -> ActionResult
end
Full name: Formlets.HomeController
type: HomeController
implements: IController
implements: IActionFilter
implements: IAuthorizationFilter
implements: IDisposable
implements: IExceptionFilter
implements: IResultFilter
inherits: Controller
inherits: ControllerBase
inherits: MarshalByRefObject
class
inherit System.Web.Mvc.ControllerBase
member ActionInvoker : System.Web.Mvc.IActionInvoker with get, set
member Dispose : unit -> unit
member HttpContext : System.Web.HttpContextBase
member ModelState : System.Web.Mvc.ModelStateDictionary
member Request : System.Web.HttpRequestBase
member Response : System.Web.HttpResponseBase
member RouteData : System.Web.Routing.RouteData
member Server : System.Web.HttpServerUtilityBase
member Session : System.Web.HttpSessionStateBase
member TempDataProvider : System.Web.Mvc.ITempDataProvider with get, set
member Url : System.Web.Mvc.UrlHelper with get, set
member User : System.Security.Principal.IPrincipal
end
Full name: System.Web.Mvc.Controller
type: Controller
implements: IController
implements: IActionFilter
implements: IAuthorizationFilter
implements: IDisposable
implements: IExceptionFilter
implements: IResultFilter
inherits: ControllerBase
inherits: MarshalByRefObject
val int : 'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
type: int<'Measure>
implements: IComparable
implements: IConvertible
implements: IFormattable
implements: IComparable<int<'Measure>>
implements: IEquatable<int<'Measure>>
inherits: ValueType
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
type: int
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: IComparable<int>
implements: IEquatable<int>
inherits: ValueType
type: int
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: IComparable<int>
implements: IEquatable<int>
inherits: ValueType
type: int
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: IComparable<int>
implements: IEquatable<int>
inherits: ValueType
type: int
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: IComparable<int>
implements: IEquatable<int>
inherits: ValueType
struct
new : int64 -> System.DateTime
new : int64 * System.DateTimeKind -> System.DateTime
new : int * int * int -> System.DateTime
new : int * int * int * System.Globalization.Calendar -> System.DateTime
new : int * int * int * int * int * int -> System.DateTime
new : int * int * int * int * int * int * System.DateTimeKind -> System.DateTime
new : int * int * int * int * int * int * System.Globalization.Calendar -> System.DateTime
new : int * int * int * int * int * int * int -> System.DateTime
new : int * int * int * int * int * int * int * System.DateTimeKind -> System.DateTime
new : int * int * int * int * int * int * int * System.Globalization.Calendar -> System.DateTime
new : int * int * int * int * int * int * int * System.Globalization.Calendar * System.DateTimeKind -> System.DateTime
member Add : System.TimeSpan -> System.DateTime
member AddDays : float -> System.DateTime
member AddHours : float -> System.DateTime
member AddMilliseconds : float -> System.DateTime
member AddMinutes : float -> System.DateTime
member AddMonths : int -> System.DateTime
member AddSeconds : float -> System.DateTime
member AddTicks : int64 -> System.DateTime
member AddYears : int -> System.DateTime
member CompareTo : obj -> int
member CompareTo : System.DateTime -> int
member Date : System.DateTime
member Day : int
member DayOfWeek : System.DayOfWeek
member DayOfYear : int
member Equals : obj -> bool
member Equals : System.DateTime -> bool
member GetDateTimeFormats : unit -> string []
member GetDateTimeFormats : System.IFormatProvider -> string []
member GetDateTimeFormats : char -> string []
member GetDateTimeFormats : char * System.IFormatProvider -> string []
member GetHashCode : unit -> int
member GetTypeCode : unit -> System.TypeCode
member Hour : int
member IsDaylightSavingTime : unit -> bool
member Kind : System.DateTimeKind
member Millisecond : int
member Minute : int
member Month : int
member Second : int
member Subtract : System.DateTime -> System.TimeSpan
member Subtract : System.TimeSpan -> System.DateTime
member Ticks : int64
member TimeOfDay : System.TimeSpan
member ToBinary : unit -> int64
member ToFileTime : unit -> int64
member ToFileTimeUtc : unit -> int64
member ToLocalTime : unit -> System.DateTime
member ToLongDateString : unit -> string
member ToLongTimeString : unit -> string
member ToOADate : unit -> float
member ToShortDateString : unit -> string
member ToShortTimeString : unit -> string
member ToString : unit -> string
member ToString : string -> string
member ToString : System.IFormatProvider -> string
member ToString : string * System.IFormatProvider -> string
member ToUniversalTime : unit -> System.DateTime
member Year : int
static val MinValue : System.DateTime
static val MaxValue : System.DateTime
static member Compare : System.DateTime * System.DateTime -> int
static member DaysInMonth : int * int -> int
static member Equals : System.DateTime * System.DateTime -> bool
static member FromBinary : int64 -> System.DateTime
static member FromFileTime : int64 -> System.DateTime
static member FromFileTimeUtc : int64 -> System.DateTime
static member FromOADate : float -> System.DateTime
static member IsLeapYear : int -> bool
static member Now : System.DateTime
static member Parse : string -> System.DateTime
static member Parse : string * System.IFormatProvider -> System.DateTime
static member Parse : string * System.IFormatProvider * System.Globalization.DateTimeStyles -> System.DateTime
static member ParseExact : string * string * System.IFormatProvider -> System.DateTime
static member ParseExact : string * string * System.IFormatProvider * System.Globalization.DateTimeStyles -> System.DateTime
static member ParseExact : string * string [] * System.IFormatProvider * System.Globalization.DateTimeStyles -> System.DateTime
static member SpecifyKind : System.DateTime * System.DateTimeKind -> System.DateTime
static member Today : System.DateTime
static member TryParse : string * System.DateTime -> bool
static member TryParse : string * System.IFormatProvider * System.Globalization.DateTimeStyles * System.DateTime -> bool
static member TryParseExact : string * string * System.IFormatProvider * System.Globalization.DateTimeStyles * System.DateTime -> bool
static member TryParseExact : string * string [] * System.IFormatProvider * System.Globalization.DateTimeStyles * System.DateTime -> bool
static member UtcNow : System.DateTime
end
Full name: System.DateTime
type: DateTime
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: Runtime.Serialization.ISerializable
implements: IComparable<DateTime>
implements: IEquatable<DateTime>
inherits: ValueType
type: string
implements: IComparable
implements: ICloneable
implements: IConvertible
implements: IComparable<string>
implements: seq<char>
implements: Collections.IEnumerable
implements: IEquatable<string>
type: DateTime
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: Runtime.Serialization.ISerializable
implements: IComparable<DateTime>
implements: IEquatable<DateTime>
inherits: ValueType
type: DateTime
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: Runtime.Serialization.ISerializable
implements: IComparable<DateTime>
implements: IEquatable<DateTime>
inherits: ValueType
type: int
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: IComparable<int>
implements: IEquatable<int>
inherits: ValueType
type: HomeController
implements: IController
implements: IActionFilter
implements: IAuthorizationFilter
implements: IDisposable
implements: IExceptionFilter
implements: IResultFilter
inherits: Controller
inherits: ControllerBase
inherits: MarshalByRefObject
Full name: Formlets.HomeController.Index
Controller.View() : ViewResult
Controller.View(view: IView) : ViewResult
Controller.View(viewName: string) : ViewResult
Controller.View(model: obj) : ViewResult
Controller.View(view: IView, model: obj) : ViewResult
Controller.View(viewName: string, model: obj) : ViewResult
Controller.View(viewName: string, masterName: string) : ViewResult
Controller.View(viewName: string, masterName: string, model: obj) : ViewResult
Full name: Microsoft.FSharp.Core.Operators.box
Full name: Formlets.Formlet.render
class
member ExecuteResult : System.Web.Mvc.ControllerContext -> unit
end
Full name: System.Web.Mvc.ActionResult
Full name: Formlets.HomeController.Register
type: (string * string) list
implements: Collections.IStructuralEquatable
implements: IComparable<List<string * string>>
implements: IComparable
implements: Collections.IStructuralComparable
implements: IEnumerable<string * string>
implements: Collections.IEnumerable
Full name: Formlets.Formlet.fromNV
type: DateTime
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: Runtime.Serialization.ISerializable
implements: IComparable<DateTime>
implements: IEquatable<DateTime>
inherits: ValueType
type: DateTime
implements: IComparable
implements: IFormattable
implements: IConvertible
implements: Runtime.Serialization.ISerializable
implements: IComparable<DateTime>
implements: IEquatable<DateTime>
inherits: ValueType
No comments:
Post a Comment