diff --git a/README.md b/README.md index d4bad3e5..9130975b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Sanctuary -Sanctuary is a small functional programming library inspired by Haskell -and PureScript. It depends on and works nicely with [Ramda][]. Sanctuary +Sanctuary is a functional programming library inspired by Haskell and +PureScript. It depends on and works nicely with [Ramda][]. Sanctuary makes it possible to write safe code without null checks. In JavaScript it's trivial to introduce a possible run-time type error: @@ -49,11 +49,81 @@ _When the `map` method is invoked on a value of type `Maybe a` (for any type `a`) with an argument of type `a -> b` (for any type `b`), it returns a value of type `Maybe b`._ +### Accessible pseudotype + +What is the type of values which support property access? In other words, +what is the type of which every value except `null` and `undefined` is a +member? Object is close, but `Object.create(null)` produces a value which +supports property access but which is not a member of the Object type. + +Sanctuary uses the Accessible pseudotype to represent the set of values +which support property access. + +### Integer pseudotype + +The Integer pseudotype represents integers in the range (-2^53 .. 2^53). +It is a pseudotype because each Integer is represented by a Number value. +Sanctuary's run-time type checking asserts that a valid Number value is +provided wherever an Integer value is required. + +### List pseudotype + +The List pseudotype represents non-Function values with numeric `length` +properties greater than or equal to zero, such as `[1, 2, 3]` and `'foo'`. + +### Type representatives + +What is the type of `Number`? One answer is `a -> Number`, since it's a +function which takes an argument of any type and returns a Number value. +When provided as the first argument to [`is`](#is), though, `Number` is +really the value-level representative of the Number type. + +Sanctuary uses the TypeRep pseudotype to describe type representatives. +For example: + + Number :: TypeRep Number + +`Number` is the sole inhabitant of the TypeRep Number type. + ## API +### Classify + +

is :: TypeRep a -> b -> Boolean

+ +Takes a [type representative](#type-representatives) and a value of +any type and returns `true` if the given value is of the specified +type (either directly or via the prototype chain); `false` otherwise. + +Boolean, number, string, and symbol [primitives][] are promoted to +their object equivalents. `42`, for example, is considered a Number +and an Object (whereas [`R.is`][R.is] considers it a Number but not +an Object). + +```javascript +> S.is(Number, 42) +true + +> S.is(Object, 42) +true + +> S.is(String, 42) +false +``` + ### Combinator -

K :: a -> b -> a

+

I :: a -> a

+ +The I combinator. Returns its argument. Equivalent to Haskell's `id` +function. + +```javascript +> S.I('foo') +"foo" +``` + +

K :: a -> b -> a

The K combinator. Takes two values and returns the first. Equivalent to Haskell's `const` function. @@ -61,20 +131,83 @@ Haskell's `const` function. ```javascript > S.K('foo', 'bar') "foo" + > R.map(S.K(42), R.range(0, 5)) [42, 42, 42, 42, 42] ``` +### Composition + +

compose :: (b -> c) -> (a -> b) -> a -> c

+ +Takes two functions assumed to be unary and a value of any type, +and returns the result of applying the first function to the result +of applying the second function to the given value. + +In general terms, `compose` performs right-to-left composition of two +unary functions. + +See also [`pipe`](#pipe). + +```javascript +> S.compose(Math.sqrt, R.inc)(99) +10 +``` + +

pipe :: [(a -> b), (b -> c), ..., (m -> n)] -> a -> n

+ +Takes a list of functions assumed to be unary and a value of any type, +and returns the result of applying the sequence of transformations to +the initial value. + +In general terms, `pipe` performs left-to-right composition of a list +of functions. `pipe([f, g, h], x)` is equivalent to `h(g(f(x)))`. + +See also [`meld`](#meld). + +```javascript +> S.pipe([R.inc, Math.sqrt, R.dec])(99) +9 +``` + +

meld :: [** -> *] -> (* -> * -> ... -> *)

+ +Takes a list of non-nullary functions and returns a curried function +whose arity is one greater than the sum of the arities of the given +functions less the number of functions. + +The behaviour of `meld` is best conveyed diagrammatically. The following +diagram depicts the "melding" of binary functions `f` and `g`: + + +-------+ + --- a --->| | + | f | +-------+ + --- b --->| |--- f(a, b) --->| | + +-------+ | g | + --- c ---------------------------->| |--- g(f(a, b), c) ---> + +-------+ + +See also [`pipe`](#pipe). + +```javascript +> S.meld([Math.pow, R.subtract])(3, 4, 5) +76 + +> S.meld([Math.pow, R.subtract])(3)(4)(5) +76 +``` + ### Maybe type -

Maybe :: Type

+

Maybe :: TypeRep Maybe

The Maybe type represents optional values: a value of type `Maybe a` is either a Just whose value is of type `a` or a Nothing (with no value). -The Maybe type satisfies the [Monoid][] and [Monad][] specifications. +The Maybe type satisfies the [Monoid][], [Monad][], [Foldable][], and +[Extend][] specifications. -

Maybe.empty :: -> Maybe a

+

Maybe.empty :: -> Maybe a

Returns a Nothing. @@ -83,7 +216,7 @@ Returns a Nothing. Nothing() ``` -

Maybe.of :: a -> Maybe a

+

Maybe.of :: a -> Maybe a

Takes a value of any type and returns a Just with the given value. @@ -92,7 +225,7 @@ Takes a value of any type and returns a Just with the given value. Just(42) ``` -

Maybe#ap :: Maybe (a -> b) ~> Maybe a -> Maybe b

+

Maybe#ap :: Maybe (a -> b) ~> Maybe a -> Maybe b

Takes a value of type `Maybe a` and returns a Nothing unless `this` is a Just *and* the argument is a Just, in which case it returns a @@ -110,7 +243,7 @@ Nothing() Just(43) ``` -

Maybe#chain :: Maybe a ~> (a -> Maybe b) -> Maybe b

+

Maybe#chain :: Maybe a ~> (a -> Maybe b) -> Maybe b

Takes a function and returns `this` if `this` is a Nothing; otherwise it returns the result of applying the function to this Just's value. @@ -126,7 +259,7 @@ Nothing() Just(12.34) ``` -

Maybe#concat :: Maybe a ~> Maybe a -> Maybe a

+

Maybe#concat :: Maybe a ~> Maybe a -> Maybe a

Returns the result of concatenating two Maybe values of the same type. `a` must have a [Semigroup][] (indicated by the presence of a `concat` @@ -155,7 +288,7 @@ Just([1, 2, 3]) Just([1, 2, 3]) ``` -

Maybe#empty :: Maybe a ~> Maybe a

+

Maybe#empty :: Maybe a ~> Maybe a

Returns a Nothing. @@ -164,7 +297,7 @@ Returns a Nothing. Nothing() ``` -

Maybe#equals :: Maybe a ~> b -> Boolean

+

Maybe#equals :: Maybe a ~> b -> Boolean

Takes a value of any type and returns `true` if: @@ -190,7 +323,21 @@ false false ``` -

Maybe#filter :: Maybe a ~> (a -> Boolean) -> Maybe a

+

Maybe#extend :: Maybe a ~> (Maybe a -> a) -> Maybe a

+ +Takes a function and returns `this` if `this` is a Nothing; otherwise +it returns a Just whose value is the result of applying the function to +`this`. + +```javascript +> S.Nothing().extend(function(x) { return x.value + 1; }) +Nothing() + +> S.Just(42).extend(function(x) { return x.value + 1; }) +Just(43) +``` + +

Maybe#filter :: Maybe a ~> (a -> Boolean) -> Maybe a

Takes a predicate and returns `this` if `this` is a Just whose value satisfies the predicate; Nothing otherwise. @@ -203,7 +350,7 @@ Just(42) Nothing() ``` -

Maybe#map :: Maybe a ~> (a -> b) -> Maybe b

+

Maybe#map :: Maybe a ~> (a -> b) -> Maybe b

Takes a function and returns `this` if `this` is a Nothing; otherwise it returns a Just whose value is the result of applying the function to @@ -213,11 +360,11 @@ this Just's value. > S.Nothing().map(R.inc) Nothing() -> S.Just(42).map(R.inc) -Just(43) +> S.Just([1, 2, 3]).map(R.sum) +Just(6) ``` -

Maybe#of :: Maybe a ~> b -> Maybe b

+

Maybe#of :: Maybe a ~> b -> Maybe b

Takes a value of any type and returns a Just with the given value. @@ -226,7 +373,24 @@ Takes a value of any type and returns a Just with the given value. Just(42) ``` -

Maybe#toBoolean :: Maybe a ~> Boolean

+

Maybe#reduce :: Maybe a ~> (b -> a -> b) -> b -> b

+ +Takes a function and an initial value of any type, and returns: + + - the initial value if `this` is a Nothing; otherwise + + - the result of applying the function to the initial value and this + Just's value. + +```javascript +> S.Nothing().reduce(R.add, 10) +10 + +> S.Just(5).reduce(R.add, 10) +15 +``` + +

Maybe#toBoolean :: Maybe a ~> Boolean

Returns `false` if `this` is a Nothing; `true` if `this` is a Just. @@ -238,7 +402,7 @@ false true ``` -

Maybe#toString :: Maybe a ~> String

+

Maybe#toString :: Maybe a ~> String

Returns the string representation of the Maybe. @@ -250,12 +414,12 @@ Returns the string representation of the Maybe. "Just([1, 2, 3])" ``` -

Maybe#type :: Type

+

Maybe#type :: TypeRep Maybe

A reference to the Maybe type. Useful for determining whether two values such as `S.Nothing()` and `S.Just(42)` are of the same type. -

Nothing :: -> Maybe a

+

Nothing :: -> Maybe a

Returns a Nothing. Though this is a constructor function the `new` keyword needn't be used. @@ -265,7 +429,7 @@ keyword needn't be used. Nothing() ``` -

Just :: a -> Maybe a

+

Just :: a -> Maybe a

Takes a value of any type and returns a Just with the given value. Though this is a constructor function the `new` keyword needn't be @@ -276,7 +440,7 @@ used. Just(42) ``` -

fromMaybe :: a -> Maybe a -> a

+

fromMaybe :: a -> Maybe a -> a

Takes a default value and a Maybe, and returns the Maybe's value if the Maybe is a Just; the default value otherwise. @@ -289,7 +453,7 @@ if the Maybe is a Just; the default value otherwise. 0 ``` -

toMaybe :: a? -> Maybe a

+

toMaybe :: a? -> Maybe a

Takes a value and returns Nothing if the value is null or undefined; Just the value otherwise. @@ -302,13 +466,53 @@ Nothing() Just(42) ``` -

encase :: (* -> a) -> (* -> Maybe a)

+

maybe :: b -> (a -> b) -> Maybe a -> b

+ +Takes a value of any type, a function, and a Maybe. If the Maybe is +a Just, the return value is the result of applying the function to +the Just's value. Otherwise, the first argument is returned. + +```javascript +> S.maybe(0, R.length, S.Just('refuge')) +6 + +> S.maybe(0, R.length, S.Nothing()) +0 +``` + +

catMaybes :: [Maybe a] -> [a]

+ +Takes a list of Maybes and returns a list containing each Just's value. + +```javascript +> S.catMaybes([S.Just('foo'), S.Nothing(), S.Just('baz')]) +["foo", "baz"] +``` + +

mapMaybe :: (a -> Maybe b) -> [a] -> [b]

+ +Takes a function and a list, applies the function to each element of +the list, and returns a list of "successful" results. If the result of +applying the function to an element of the list is a Nothing, the result +is discarded; if the result is a Just, the Just's value is included in +the output list. + +In general terms, `mapMaybe` filters a list while mapping over it. + +```javascript +> S.mapMaybe(S.head, [[], [1, 2, 3], [], [4, 5, 6], []]) +[1, 4] +``` + +

encase :: (* -> a) -> (* -> Maybe a)

Takes a function `f` which may throw and returns a curried function `g` which will not throw. The result of applying `g` is determined by applying `f` to the same arguments: if this succeeds, `g` returns Just the result; otherwise `g` returns Nothing. +See also [`encaseEither`](#encaseEither). + ```javascript > S.encase(eval)('1 + 1') Just(2) @@ -319,15 +523,16 @@ Nothing() ### Either type -

Either :: Type

+

Either :: TypeRep Either

The Either type represents values with two possibilities: a value of type `Either a b` is either a Left whose value is of type `a` or a Right whose value is of type `b`. -The Either type satisfies the [Semigroup][] and [Monad][] specifications. +The Either type satisfies the [Semigroup][], [Monad][], and [Extend][] +specifications. -

Either.of :: b -> Either a b

+

Either.of :: b -> Either a b

Takes a value of any type and returns a Right with the given value. @@ -336,7 +541,7 @@ Takes a value of any type and returns a Right with the given value. Right(42) ``` -

Either#ap :: Either a (b -> c) ~> Either a b -> Either a c

+

Either#ap :: Either a (b -> c) ~> Either a b -> Either a c

Takes a value of type `Either a b` and returns a Left unless `this` is a Right *and* the argument is a Right, in which case it returns @@ -354,7 +559,7 @@ Left("Cannot divide by zero") Right(43) ``` -

Either#chain :: Either a b ~> (b -> Either a c) -> Either a c

+

Either#chain :: Either a b ~> (b -> Either a c) -> Either a c

Takes a function and returns `this` if `this` is a Left; otherwise it returns the result of applying the function to this Right's value. @@ -373,7 +578,7 @@ Left("Cannot represent square root of negative number") Right(5) ``` -

Either#concat :: Either a b ~> Either a b -> Either a b

+

Either#concat :: Either a b ~> Either a b -> Either a b

Returns the result of concatenating two Either values of the same type. `a` must have a [Semigroup][] (indicated by the presence of a `concat` @@ -403,7 +608,7 @@ Right([1, 2, 3]) Right([1, 2, 3]) ``` -

Either#equals :: Either a b ~> c -> Boolean

+

Either#equals :: Either a b ~> c -> Boolean

Takes a value of any type and returns `true` if: @@ -424,7 +629,21 @@ false false ``` -

Either#map :: Either a b ~> (b -> c) -> Either a c

+

Either#extend :: Either a b ~> (Either a b -> b) -> Either a b

+ +Takes a function and returns `this` if `this` is a Left; otherwise it +returns a Right whose value is the result of applying the function to +`this`. + +```javascript +> S.Left('Cannot divide by zero').extend(function(x) { return x.value + 1; }) +Left("Cannot divide by zero") + +> S.Right(42).extend(function(x) { return x.value + 1; }) +Right(43) +``` + +

Either#map :: Either a b ~> (b -> c) -> Either a c

Takes a function and returns `this` if `this` is a Left; otherwise it returns a Right whose value is the result of applying the function to @@ -434,11 +653,11 @@ this Right's value. > S.Left('Cannot divide by zero').map(R.inc) Left("Cannot divide by zero") -> S.Right(42).map(R.inc) -Right(43) +> S.Right([1, 2, 3]).map(R.sum) +Right(6) ``` -

Either#of :: Either a b ~> b -> Either a b

+

Either#of :: Either a b ~> b -> Either a b

Takes a value of any type and returns a Right with the given value. @@ -447,7 +666,7 @@ Takes a value of any type and returns a Right with the given value. Right(42) ``` -

Either#toBoolean :: Either a b ~> Boolean

+

Either#toBoolean :: Either a b ~> Boolean

Returns `false` if `this` is a Left; `true` if `this` is a Right. @@ -459,7 +678,7 @@ false true ``` -

Either#toString :: Either a b ~> String

+

Either#toString :: Either a b ~> String

Returns the string representation of the Either. @@ -471,13 +690,13 @@ Returns the string representation of the Either. "Right([1, 2, 3])" ``` -

Either#type :: Type

+

Either#type :: TypeRep Either

A reference to the Either type. Useful for determining whether two values such as `S.Left('Cannot divide by zero')` and `S.Right(42)` are of the same type. -

Left :: a -> Either a b

+

Left :: a -> Either a b

Takes a value of any type and returns a Left with the given value. Though this is a constructor function the `new` keyword needn't be @@ -488,7 +707,7 @@ used. Left("Cannot divide by zero") ``` -

Right :: b -> Either a b

+

Right :: b -> Either a b

Takes a value of any type and returns a Right with the given value. Though this is a constructor function the `new` keyword needn't be @@ -499,7 +718,7 @@ used. Right(42) ``` -

either :: (a -> c) -> (b -> c) -> Either a b -> c

+

either :: (a -> c) -> (b -> c) -> Either a b -> c

Takes two functions and an Either, and returns the result of applying the first function to the Left's value, if the Either @@ -514,9 +733,47 @@ Right's value, if the Either is a Right. "42" ``` +

encaseEither :: (Error -> a) -> (* -> b) -> (* -> Either a b)

+ +Takes two functions, `f` and `g`, the second of which may throw, +and returns a curried function of the same arity as `g` which will +not throw. The result of applying this function is determined by +applying `g` to the same arguments: if this succeeds, the return +value is a Right whose value is the result; otherwise the return +value is a Left whose value is the result of applying `f` to the +caught Error object. + +See also [`encase`](#encase). + +```javascript +> S.encaseEither(R.identity, Array)(0) +Right([]) + +> S.encaseEither(R.identity, Array)(-1) +Left(RangeError: Invalid array length) + +> S.encaseEither(R.prop('message'), Array)(-1) +Left("Invalid array length") +``` + +

maybeToEither :: a -> Maybe b -> Either a b

+ +Takes a value of any type and a Maybe, and returns an Either. +If the second argument is a Nothing, a Left containing the first +argument is returned. If the second argument is a Just, a Right +containing the Just's value is returned. + +```javascript +> S.maybeToEither('Expecting an integer', S.parseInt(10, 'xyz')) +Left("Expecting an integer") + +> S.maybeToEither('Expecting an integer', S.parseInt(10, '42')) +Right(42) +``` + ### Control -

and :: a -> a -> a

+

and :: a -> a -> a

Takes two values of the same type and returns the second value if the first is "true"; the first value otherwise. An array is @@ -532,7 +789,7 @@ Just(2) Nothing() ``` -

or :: a -> a -> a

+

or :: a -> a -> a

Takes two values of the same type and returns the first value if it is "true"; the second value otherwise. An array is considered "true" @@ -547,7 +804,7 @@ Just(1) Just(3) ``` -

xor :: a -> a -> a

+

xor :: a -> a -> a

Takes two values of the same type and returns the "true" value if one value is "true" and the other is "false"; otherwise it @@ -566,7 +823,7 @@ Nothing() ### List -

slice :: Number -> Number -> [a] -> Maybe [a]

+

slice :: Integer -> Integer -> [a] -> Maybe [a]

Returns Just a list containing the elements from the supplied list from a beginning index (inclusive) to an end index (exclusive). @@ -595,7 +852,7 @@ Nothing() Just("nana") ``` -

at :: Number -> [a] -> Maybe a

+

at :: Integer -> [a] -> Maybe a

Takes an index and a list and returns Just the element of the list at the index if the index is within the list's bounds; Nothing otherwise. @@ -612,7 +869,7 @@ Nothing() Just("d") ``` -

head :: [a] -> Maybe a

+

head :: [a] -> Maybe a

Takes a list and returns Just the first element of the list if the list contains at least one element; Nothing if the list is empty. @@ -625,7 +882,7 @@ Just(1) Nothing() ``` -

last :: [a] -> Maybe a

+

last :: [a] -> Maybe a

Takes a list and returns Just the last element of the list if the list contains at least one element; Nothing if the list is empty. @@ -638,7 +895,7 @@ Just(3) Nothing() ``` -

tail :: [a] -> Maybe [a]

+

tail :: [a] -> Maybe [a]

Takes a list and returns Just a list containing all but the first of the list's elements if the list contains at least one element; @@ -652,7 +909,7 @@ Just([2, 3]) Nothing() ``` -

init :: [a] -> Maybe [a]

+

init :: [a] -> Maybe [a]

Takes a list and returns Just a list containing all but the last of the list's elements if the list contains at least one element; @@ -666,7 +923,7 @@ Just([1, 2]) Nothing() ``` -

take :: Number -> [a] -> Maybe [a]

+

take :: Integer -> [a] -> Maybe [a]

Returns Just the first N elements of the given collection if N is greater than or equal to zero and less than or equal to the length @@ -684,7 +941,25 @@ Just("abcd") Nothing() ``` -

drop :: Number -> [a] -> Maybe [a]

+

takeLast :: Integer -> [a] -> Maybe [a]

+ +Returns Just the last N elements of the given collection if N is +greater than or equal to zero and less than or equal to the length +of the collection; Nothing otherwise. Supports Array, String, and +any other collection type which provides a `slice` method. + +```javascript +> S.takeLast(2, ['a', 'b', 'c', 'd', 'e']) +Just(["d", "e"]) + +> S.takeLast(4, 'abcdefg') +Just("defg") + +> S.takeLast(4, ['a', 'b', 'c']) +Nothing() +``` + +

drop :: Integer -> [a] -> Maybe [a]

Returns Just all but the first N elements of the given collection if N is greater than or equal to zero and less than or equal to the @@ -702,7 +977,25 @@ Just("efg") Nothing() ``` -

find :: (a -> Boolean) -> [a] -> Maybe a

+

dropLast :: Integer -> [a] -> Maybe [a]

+ +Returns Just all but the last N elements of the given collection +if N is greater than or equal to zero and less than or equal to the +length of the collection; Nothing otherwise. Supports Array, String, +and any other collection type which provides a `slice` method. + +```javascript +> S.dropLast(2, ['a', 'b', 'c', 'd', 'e']) +Just(["a", "b", "c"]) + +> S.dropLast(4, 'abcdefg') +Just("abc") + +> S.dropLast(4, 'abc') +Nothing() +``` + +

find :: (a -> Boolean) -> [a] -> Maybe a

Takes a predicate and a list and returns Just the leftmost element of the list which satisfies the predicate; Nothing if none of the list's @@ -716,14 +1009,14 @@ Just(-2) Nothing() ``` -

indexOf :: a -> [a] -> Maybe Number

+

indexOf :: a -> [a] -> Maybe Integer

Takes a value of any type and a list, and returns Just the index of the first occurrence of the value in the list, if applicable; Nothing otherwise. Dispatches to its second argument's `indexOf` method if present. -As a result, `String -> String -> Maybe Number` is an alternative +As a result, `String -> String -> Maybe Integer` is an alternative type signature. ```javascript @@ -740,14 +1033,14 @@ Just(1) Nothing() ``` -

lastIndexOf :: a -> [a] -> Maybe Number

+

lastIndexOf :: a -> [a] -> Maybe Integer

Takes a value of any type and a list, and returns Just the index of the last occurrence of the value in the list, if applicable; Nothing otherwise. Dispatches to its second argument's `lastIndexOf` method if present. -As a result, `String -> String -> Maybe Number` is an alternative +As a result, `String -> String -> Maybe Integer` is an alternative type signature. ```javascript @@ -764,53 +1057,69 @@ Just(3) Nothing() ``` -

pluck :: String -> [{String: *}] -> [Maybe *]

+

pluck :: TypeRep a -> String -> [Accessible] -> [Maybe a]

-Takes a list of objects and plucks the value of the specified key -for each object in the list. Returns the value wrapped in a Just -if an object has the key and a Nothing if it does not. +Takes a [type representative](#type-representatives), a property name, +and a list of objects and returns a list of equal length. Each element +of the output list is Just the value of the specified property of the +corresponding object if the value is of the specified type (according +to [`is`](#is)); Nothing otherwise. -```javascript -> S.pluck('a', [{a: 1, b: 2}, {a: 4, b: 5}, {b: 3, c: 7}]) -[Just(1), Just(4), Nothing()] +See also [`get`](#get). -> S.pluck('x', [{x: 1}, {x: 2}, {x: undefined}]) -[Just(1), Just(2), Just(undefined)] +```javascript +> S.pluck(Number, 'x', [{x: 1}, {x: 2}, {x: '3'}, {x: null}, {}]) +[Just(1), Just(2), Nothing(), Nothing(), Nothing()] ``` ### Object -

get :: String -> Object -> Maybe *

+

get :: TypeRep a -> String -> Accessible -> Maybe a

-Takes a property name and an object and returns Just the value of -the specified property of the object if the object has such an own -property; Nothing otherwise. +Takes a [type representative](#type-representatives), a property +name, and an object and returns Just the value of the specified object +property if it is of the specified type (according to [`is`](#is)); +Nothing otherwise. + +The `Object` type representative may be used as a catch-all since most +values have `Object.prototype` in their prototype chains. + +See also [`gets`](#gets). ```javascript -> S.get('x', {x: 1, y: 2}) +> S.get(Number, 'x', {x: 1, y: 2}) Just(1) -> S.get('toString', {x: 1, y: 2}) +> S.get(Number, 'x', {x: '1', y: '2'}) +Nothing() + +> S.get(Number, 'x', {}) Nothing() ``` -

gets :: [String] -> Object -> Maybe *

+

gets :: TypeRep a -> [String] -> Accessible -> Maybe a

+ +Takes a [type representative](#type-representatives), a list of property +names, and an object and returns Just the value at the path specified by +the list of property names if such a path exists and the value is of the +specified type; Nothing otherwise. -Takes a list of property names and an object and returns Just the -value at the path specified by the list of property names if such -a path exists; Nothing otherwise. +See also [`get`](#get). ```javascript -> S.gets(['a', 'b', 'c'], {a: {b: {c: 42}}}) +> S.gets(Number, ['a', 'b', 'c'], {a: {b: {c: 42}}}) Just(42) -> S.gets(['a', 'b', 'c'], {}) +> S.gets(Number, ['a', 'b', 'c'], {a: {b: {c: '42'}}}) +Nothing() + +> S.gets(Number, ['a', 'b', 'c'], {}) Nothing() ``` ### Parse -

parseDate :: String -> Maybe Date

+

parseDate :: String -> Maybe Date

Takes a string and returns Just the date represented by the string if it does in fact represent a date; Nothing otherwise. @@ -823,7 +1132,7 @@ Just(new Date("2011-01-19T17:40:00.000Z")) Nothing() ``` -

parseFloat :: String -> Maybe Number

+

parseFloat :: String -> Maybe Number

Takes a string and returns Just the number represented by the string if it does in fact represent a number; Nothing otherwise. @@ -836,7 +1145,7 @@ Just(-123.45) Nothing() ``` -

parseInt :: Number -> String -> Maybe Number

+

parseInt :: Integer -> String -> Maybe Integer

Takes a radix (an integer between 2 and 36 inclusive) and a string, and returns Just the number represented by the string if it does in @@ -858,7 +1167,7 @@ Just(255) Nothing() ``` -

parseJson :: String -> Maybe *

+

parseJson :: String -> Maybe *

Takes a string which may or may not be valid JSON, and returns Just the result of applying `JSON.parse` to the string if valid; Nothing @@ -874,7 +1183,7 @@ Nothing() ### RegExp -

match :: RegExp -> String -> Maybe [Maybe String]

+

match :: RegExp -> String -> Maybe [Maybe String]

Takes a pattern and a string, and returns Just a list of matches if the pattern matches the string; Nothing otherwise. Each match @@ -889,10 +1198,65 @@ Just([Just("goodbye"), Just("good")]) Just([Just("bye"), Nothing()]) ``` +### String + +

words :: String -> [String]

+ +Takes a string and returns the list of words the string contains +(words are delimited by whitespace characters). + +See also [`unwords`](#unwords). + +```javascript +> S.words(' foo bar baz ') +["foo", "bar", "baz"] +``` + +

unwords :: [String] -> String

+ +Takes a list of words and returns the result of joining the words +with separating spaces. + +See also [`words`](#words). + +```javascript +> S.unwords(['foo', 'bar', 'baz']) +"foo bar baz" +``` + +

lines :: String -> [String]

+ +Takes a string and returns the list of lines the string contains +(lines are delimited by newlines: `'\n'` or `'\r\n'` or `'\r'`). +The resulting strings do not contain newlines. + +See also [`unlines`](#unlines). + +```javascript +> S.lines('foo\nbar\nbaz\n') +["foo", "bar", "baz"] +``` + +

unlines :: [String] -> String

+ +Takes a list of lines and returns the result of joining the lines +after appending a terminating line feed (`'\n'`) to each. + +See also [`lines`](#lines). + +```javascript +> S.unlines(['foo', 'bar', 'baz']) +"foo\nbar\nbaz\n" +``` + +[Extend]: https://github.com/fantasyland/fantasy-land#extend +[Foldable]: https://github.com/fantasyland/fantasy-land#foldable [Monad]: https://github.com/fantasyland/fantasy-land#monad [Monoid]: https://github.com/fantasyland/fantasy-land#monoid [R.equals]: http://ramdajs.com/docs/#equals +[R.is]: http://ramdajs.com/docs/#is [R.map]: http://ramdajs.com/docs/#map [Ramda]: http://ramdajs.com/ [Semigroup]: https://github.com/fantasyland/fantasy-land#semigroup [parseInt]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt +[primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive diff --git a/bower.json b/bower.json index bfc314c7..8beb7c99 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "sanctuary", - "version": "0.6.0", + "version": "0.7.0", "description": "Refuge from unsafe JavaScript", "license": "MIT", "repository": { diff --git a/package.json b/package.json index 54644801..1843f5e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sanctuary", - "version": "0.6.0", + "version": "0.7.0", "description": "Refuge from unsafe JavaScript", "license": "MIT", "repository": {