Skip to content

Commit

Permalink
Merge pull request #33 from phadej/assert
Browse files Browse the repository at this point in the history
typify.assert
  • Loading branch information
phadej committed Feb 9, 2014
2 parents 275178d + fbb3b79 commit 9e2bab4
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var add = typify("sum :: a : number|string => a -> a -> a", function (a, b) {
* We could write a more general, polymorphic function with type signature
* `toArray :: a : *, (array a)|a -> array a`, where `*` means _any type_.
*
* Unfortunately any type `*` is seriously any.
* Unfortunately any type `*` is seriously any.
* Types as *typify* understands them, are more like Java's interfaces or Haskell's typeclasses.
* Of course, we can iterate through them all, but we cannot deduce the most principal type (because it doesn't exist).
* So eg. function signature `id :: a : *, a -> a` behaves similarly to `id :: * -> *`, which isn't strict enough.
Expand Down Expand Up @@ -82,6 +82,13 @@ typify.check('number', 1); // => true
typify.check('number', 'foobar'); // => false
```

You could use `typify.assert` for type assertions:

```javascript
typify.check('number', 'foo'); // will throw `TypeError` exception
```


There are few predefined checkable types:

- `number`
Expand Down Expand Up @@ -147,6 +154,9 @@ typify.type("char", function(n) {
});
```

*Note:* opaque type checks should return `true`,
other *truthy* values will be considered errorneous in later versions.

You can give names to (recursive) compound types with `typify.alias`:
```javascript
typify.alias("numstr", "number|string"); // numbers or strings
Expand Down
30 changes: 28 additions & 2 deletions lib/typify.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,35 @@ function check(environment, type, variable) {

switch (arguments.length) {
case 2: return function (variable1) {
return compiled(throwAlways, variable1);
return compiled(throwAlways, variable1) === true;
};
case 3:
return compiled(throwAlways, variable);
return compiled(throwAlways, variable) === true;
}
}

function assert(environment, type, variable) {
if (arguments.length !== 2 && arguments.length !== 3) {
throw new TypeError("assert takes 1 or 2 arguments, " + (arguments.length-1) + " provided");
}

var parsed = parseCheckableType(type);
// console.log(parsed);
// console.log(JSON.stringify(parsed, null));
var compiled = compileCheckableType(environment, {}, parsed); // using empty context

switch (arguments.length) {
case 2: return function (variable1) {
var result1 = compiled(throwAlways, variable1);
if (result1 !== true) {
throw new TypeError(result1);
}
};
case 3:
var result = compiled(throwAlways, variable);
if (result !== true) {
throw new TypeError(result);
}
}
}

Expand Down Expand Up @@ -284,6 +309,7 @@ function create() {
typify.adt = adt.bind(undefined, env);
typify.instance = instance.bind(undefined, env);
typify.check = check.bind(undefined, env);
typify.assert = assert.bind(undefined, env);
typify.wrap = wrap.bind(undefined, env);
typify.version = VERSION;

Expand Down
23 changes: 23 additions & 0 deletions test/assert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* global describe, it */

"use strict";

var typify = require("../lib/typify.js");
var assert = require("assert");

describe("assert()", function () {
it("throws", function () {
assert.throws(function () { typify.assert("regexp", 1); });
typify.assert("regexp", /foo/);
});

it("is autocurried", function () {
var assertNumber = typify.assert("number");
assert.throws(function () { assertNumber("foo"); });
assertNumber(1);
});

it("takes one or two parameters", function () {
assert.throws(function () { typify.assert("regexp", 1, 2); });
});
});

0 comments on commit 9e2bab4

Please sign in to comment.