Skip to content

Commit

Permalink
Merge pull request #2 from justinwoo/examples
Browse files Browse the repository at this point in the history
add fromHomogeneous and examples
  • Loading branch information
garyb authored Nov 11, 2018
2 parents 6c5c386 + c7b1925 commit dea06f0
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 8 deletions.
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,51 @@
[![Latest release](http://img.shields.io/github/release/purescript/purescript-foreign-object.svg)](https://github.com/purescript/purescript-foreign-object/releases)
[![Build status](https://travis-ci.org/purescript/purescript-foreign-object.svg?branch=master)](https://travis-ci.org/purescript/purescript-foreign-object)

Functions for working with homogeneous JavaScript objects from PureScript.
Functions for working with homogeneous JavaScript objects from PureScript. Similar to using `Map String a` but simply reusing JavaScript objects.

## Installation

```
bower install purescript-foreign-object
```

## Example

```purs
example = do
let
-- make an empty Object
empty = FO.empty
-- insert to an empty Object
inserted = FO.insert "a" 1 empty
-- or: use the singleton function
-- singleton FO.singleton "a" 1
-- lookup values for existing in the Object as a result of Maybe
let lookup = FO.lookup "a" inserted
Assert.assertEqual { actual: lookup, expected: Just 1 }
-- delete a value from an Object
let deleted = FO.delete "a" inserted
Assert.assertEqual { actual: deleted, expected: FO.empty }
let
-- convert homogeneous records to Object
converted = FO.fromHomogeneous { a: 1, b: 2, c: 3}
-- check that the converted is equal to a regularly built Object
built
= FO.empty
# FO.insert "a" 1
# FO.insert "b" 2
# FO.insert "c" 3
Assert.assertEqual { actual: converted, expected: built }
```

See the [tests](test/Main.purs) for more examples.

## Documentation

Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-foreign-object).
10 changes: 6 additions & 4 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@
"purescript-arrays": "^5.0.0",
"purescript-foldable-traversable": "^4.0.0",
"purescript-functions": "^4.0.0",
"purescript-gen": "^2.0.0",
"purescript-gen": "^2.1.0",
"purescript-lists": "^5.0.0",
"purescript-maybe": "^4.0.0",
"purescript-prelude": "^4.0.0",
"purescript-prelude": "^4.1.0",
"purescript-st": "^4.0.0",
"purescript-tailrec": "^4.0.0",
"purescript-tuples": "^5.0.0",
"purescript-unfoldable": "^4.0.0"
"purescript-unfoldable": "^4.0.0",
"purescript-typelevel-prelude": "^3.0.0"
},
"devDependencies": {
"purescript-quickcheck": "^5.0.0",
"purescript-minibench": "^2.0.0"
"purescript-minibench": "^2.0.0",
"purescript-assert": "^4.0.0"
}
}
14 changes: 11 additions & 3 deletions src/Foreign/Object.purs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Foreign.Object
, toAscUnfoldable
, fromFoldable
, fromFoldableWith
, fromHomogeneous
, delete
, pop
, member
Expand Down Expand Up @@ -56,6 +57,8 @@ import Data.Tuple (Tuple(..), fst, uncurry)
import Data.Unfoldable (class Unfoldable)
import Foreign.Object.ST (STObject)
import Foreign.Object.ST as OST
import Type.Row.Homogeneous (class Homogeneous)
import Unsafe.Coerce (unsafeCoerce)

-- | `Object a` represents a homogeneous JS Object with values of type `a`.
foreign import data Object :: Type -> Type
Expand Down Expand Up @@ -170,7 +173,7 @@ isEmpty = all (\_ _ -> false)
-- | Calculate the number of key/value pairs in a map
foreign import size :: forall a. Object a -> Int

-- | Create a map with one key/value pair
-- | Create an `Object a` with one key/value pair
singleton :: forall a. String -> a -> Object a
singleton k v = runST (OST.poke k v =<< OST.new)

Expand Down Expand Up @@ -209,7 +212,7 @@ alter f k m = case f (k `lookup` m) of
update :: forall a. (a -> Maybe a) -> String -> Object a -> Object a
update f k m = alter (maybe Nothing f) k m

-- | Create a map from a foldable collection of key/value pairs
-- | Create an `Object a` from a foldable collection of key/value pairs
fromFoldable :: forall f a. Foldable f => f (Tuple String a) -> Object a
fromFoldable l = runST do
s <- OST.new
Expand All @@ -218,14 +221,19 @@ fromFoldable l = runST do

foreign import _lookupST :: forall a r z. Fn4 z (a -> z) String (STObject r a) (ST r z)

-- | Create a map from a foldable collection of key/value pairs, using the
-- | Create an `Object a` from a foldable collection of key/value pairs, using the
-- | specified function to combine values for duplicate keys.
fromFoldableWith :: forall f a. Foldable f => (a -> a -> a) -> f (Tuple String a) -> Object a
fromFoldableWith f l = runST (do
s <- OST.new
for_ l (\(Tuple k v) -> runFn4 _lookupST v (f v) k s >>= \v' -> OST.poke k v' s)
pure s)

-- | Create an `Object a` from a homogeneous record, i.e. all of the record
-- | fields are of the same type.
fromHomogeneous :: forall r a. Homogeneous r a => { | r } -> Object a
fromHomogeneous = unsafeCoerce

foreign import toArrayWithKey :: forall a b . (String -> a -> b) -> Object a -> Array b

-- | Unfolds a map into a list of key/value pairs
Expand Down
36 changes: 36 additions & 0 deletions test/Test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,47 @@ module Test.Main where

import Prelude

import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Console (log)
import Foreign.Object as FO
import Test.Assert as Assert
import Test.Foreign.Object (objectTests)

example :: Effect Unit
example = do
let
-- make an empty Object
empty = FO.empty

-- insert to an empty Object
inserted = FO.insert "a" 1 empty

-- or: use the singleton function
-- singleton FO.singleton "a" 1

-- lookup values for existing in the Object as a result of Maybe
let lookup = FO.lookup "a" inserted
Assert.assertEqual { actual: lookup, expected: Just 1 }

-- delete a value from an Object
let deleted = FO.delete "a" inserted
Assert.assertEqual { actual: deleted, expected: FO.empty }

let
-- convert homogeneous records to Object
converted = FO.fromHomogeneous { a: 1, b: 2, c: 3}
-- check that the converted is equal to a regularly built Object
built
= FO.empty
# FO.insert "a" 1
# FO.insert "b" 2
# FO.insert "c" 3

Assert.assertEqual { actual: converted, expected: built }

main :: Effect Unit
main = do
log "Running StrMap tests"
example
objectTests

0 comments on commit dea06f0

Please sign in to comment.