Skip to content

Instantly share code, notes, and snippets.

@johnbender
Created February 27, 2012 19:37
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save johnbender/7242a7434195565b4a9d to your computer and use it in GitHub Desktop.
Save johnbender/7242a7434195565b4a9d to your computer and use it in GitHub Desktop.

Html, Jqry, and the Functor

Asumptions/Requirements

  1. this is an implicit parameter to jqry.morphisms
  2. Type guarantees are made by the closure compiler type annotations and custom @sig type signature annotation

Category Html

Objects: HTMLElements and all subclasses
Arrows/Morphisms: pure javascript functions from HTMElement -> HTMLElement
Composition:

/** @typedef {function(HTMElement): HTMElement} */
html.morphism;

/** @sig {html.morphism}, {html.morphism} -> {html.morphism} */
function compose( f, g ){
  return function( a ) { 
    return f(g(a)); 
  };
}

Sample use:

function a( elem ){
  elem.setAttribute( "foo", "bar" );
  return elem;
}

function b( elem ){
  elem.setAttribute( "baz", "bak" );
  return elem;
}

var elem = document.getElementById( "example-anchor" );
elem.getAttribute( "foo" ); // undefined
elem.getAttribute( "baz" ); // undefined

elem = compose( a, b )( elem );
elem.getAttribute( "foo" ); // "bar"
elem.getAttribute( "baz" ); // "bak"

Identity:

/** @sig {HTMLElement} -> {HTMLElement} */
function id( a ) { 
  return a; 
}

Category Jqry

Objects: jQuery
Arrows/Morphisms: pure javascript functions from jQuery -> jQuery defined on $.fn
Composition:

/** @typedef {function(this:jQuery): jQuery} */
jqry.morphism;

/** @sig {jqry.morphism}, {jqry.morphism} -> {jqry.morphism} */
$.compose = function( f, g ){
  return function(){
    return f.apply(g.apply(this, arguments), arguments)
  };
}

Sample use:

$.fn.a = function(){
  return this.map(function( elem ){
    elem.setAttribute( "foo", "bar" );
    return elem;
  });
};

$.fn.b = function(){
  return this.map(function( elem ){
    elem.setAttribute( "baz", "bak" );
    return elem;
  });
};

var $elem = $( "#example-anchor" );
$elem.attr( "foo" );         // undefined
$elem.attr( "baz" );         // undefined
$.fn.aAndB = $.compose( $.fn.a, $.fn.b );

$elem.aAndB().attr( "foo" ); // "bar"
$elem.attr( "baz" );         // "bak"

Identity:

/** @this {jQuery}
    @return {jQuery} */
$.fn.id = function(){ return this };

Functor Html -> Jqry

Maps: HTMLElements and html.morphisms to jQuery objects and jque.morphisms respectively

/** @sig {HTMLElement | html.morphism} -> {jQuery | jqry.morphism} */
$.Functor = function( a ){
  if( typeof a == "function" ){
    return function() {
      return this.map(a);
    };
  } else {
    return $( a );
  }
};

Sample use for objects:

var elem = document.getElementsById( "example" ); 
elem.nodeName;                        // "A"
$.Functor( elem ).prop( "nodeName" ); // "A"

Sample use for functions:

$.fn.myMorphism = $.Functor(function( a ){
  a.setAttribute("foo", "bar" );
  return a;
});

$( "#example" ).attr( "foo" );              // undefined
$( "#example" ).myMorphism().attr( "foo" ); // "bar"

Identity:

var a = document.getElementById( "#example-anchor" );

assert($.Functor(id(a)) == id($.Functor(a)));

a;                // <a id="example-anchor"></a>

id(a);            // <a id="example-anchor"></a>
$.Functor(id(a)); // [<a id="example-anchor"></a>] 


$.Functor(a);     // [<a id="example-anchor"></a>]
id($.Functor(a)); // [<a id="example-anchor"></a>]

Composition:

var $elem = $( "#example-anchor" );
assert($.Functor(compose(a, b)) == $.compose($.Functor(a), $.Functor(b)));

var aAndB = compose(a, b);                           // function( elem ){ return a(b(elem)); }
$.fn.fstAB = $.Functor(aAndB);                       // function() { this.map(aAndB); }
$elem.fstAB().attr("foo");                           // "bar"
$elem.attr("baz");                                   // "bak"

$elem = $( "#second-example-anchor" );
$.Functor(a);                                        // function() { this.map(a) };
$.Functor(b);                                        // function() { this.map(b) };
$.fn.sndAB = $.compose( $.Functor(a), $.Functor(b) ) // function(){ a.apply(b.apply(this, arguments) arguments); }
$elem.sndAB().attr("foo");                           // "bar"
$elem.attr("baz");                                   // "bak"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment