Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.pulp-cache
.psci
.psci_modules/
node_modules/
Expand Down
6 changes: 5 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
],
"dependencies": {
"purescript-foreign": "~0.7.0",
"purescript-unsafe-coerce": "~0.1.0"
"purescript-maps": "~0.5.4",
"purescript-tuples": "~0.4.0",
"purescript-monoid": "~0.3.2",
"purescript-maybe": "~0.3.5",
"purescript-contravariant": "~0.2.3"
},
"devDependencies": {
"purescript-console": "~0.1.1"
Expand Down
82 changes: 52 additions & 30 deletions docs/Data/Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,99 @@
#### `Options`

``` purescript
data Options :: * -> *
newtype Options opt
```

The `Options` type represents a set of options. The type argument is a
phantom type, which is useful for ensuring that options for one particular
API are not accidentally passed to some other API.

##### Instances
``` purescript
instance semigroupOptions :: Semigroup (Options a)
instance monoidOptions :: Monoid (Options a)
Semigroup (Options opt)
Monoid (Options opt)
```

#### `Option`
#### `runOptions`

``` purescript
data Option :: * -> * -> *
runOptions :: forall opt. Options opt -> Array (Tuple String Foreign)
```

#### `IsOption`
#### `options`

``` purescript
class IsOption value where
assoc :: forall opt. Option opt value -> value -> Options opt
options :: forall opt. Options opt -> Foreign
```

##### Instances
Convert an `Options` value into a JavaScript object, suitable for passing
to JavaScript APIs.

#### `Option`

``` purescript
instance isOptionString :: IsOption String
instance isOptionBoolean :: IsOption Boolean
instance isOptionNumber :: IsOption Number
instance isOptionInt :: IsOption Int
instance isOptionRecord :: IsOption { | a }
instance isOptionUnit :: IsOption Unit
instance isOptionFunction :: IsOption (a -> b)
instance isOptionArray :: (IsOption a) => IsOption (Array a)
instance isOptionMaybe :: (IsOption a) => IsOption (Maybe a)
type Option opt = Op (Options opt)
```

#### `(:=)`
An `Option` represents an opportunity to configure a specific attribute
of a call to some API. This normally corresponds to one specific property
of an "options" object in JavaScript APIs, but can in general correspond
to zero or more actual properties.

#### `assoc`

``` purescript
(:=) :: forall opt value. (IsOption value) => Option opt value -> value -> Options opt
assoc :: forall opt value. Option opt value -> value -> Options opt
```

_right-associative / precedence 6_
Associates a value with a specific option.

#### `optionFn`
#### `(:=)`

``` purescript
optionFn :: forall opt from to. Option opt from -> Option opt to
(:=) :: forall opt value. Option opt value -> value -> Options opt
```

#### `key`
_right-associative / precedence 6_

An infix version of `assoc`.

#### `optional`

``` purescript
key :: forall opt value. Option opt value -> String
optional :: forall opt value. Option opt value -> Option opt (Maybe value)
```

A version of `assoc` which takes possibly absent values. `Nothing` values
are ignored; passing `Nothing` for the second argument will result in an
empty `Options`.

#### `opt`

``` purescript
opt :: forall opt value. (IsOption value) => String -> Option opt value
opt :: forall opt value. String -> Option opt value
```

#### `runOptions`
The default way of creating `Option` values. Constructs an `Option` with
the given key, which passes the given value through unchanged.

#### `tag`

``` purescript
runOptions :: forall a. Options a -> Array (Tuple String Foreign)
tag :: forall opt value. Option opt value -> value -> Option opt Unit
```

#### `options`
Create a `tag`, by fixing an `Option` to a single value.

#### `defaultToOptions`

``` purescript
options :: forall a. Options a -> Foreign
defaultToOptions :: forall opt value. String -> value -> Options opt
```

The default method for turning a string property key into an
`Option`. This function simply calls `toForeign` on the value. If
you need some other behaviour, you can write your own function to replace
this one, and construct an `Option` yourself.


63 changes: 0 additions & 63 deletions src/Data/Options.js

This file was deleted.

134 changes: 59 additions & 75 deletions src/Data/Options.purs
Original file line number Diff line number Diff line change
@@ -1,94 +1,78 @@
module Data.Options
( Options()
, Option()
, IsOption
, assoc, (:=)
, optionFn
, options
, runOptions
, opt, key
, options
, Option
, assoc, (:=)
, optional
, opt
, tag
, defaultToOptions
) where

import Prelude

import Data.Foreign (Foreign())

import Data.Function (Fn2(), runFn2)
import Data.Foreign (toForeign, Foreign())
import Data.Maybe (Maybe(), maybe)
import Data.Monoid (mempty, Monoid)
import Data.Op (Op(Op), runOp)
import Data.StrMap as StrMap
import Data.Tuple (Tuple(..))

import Data.Maybe (Maybe(..))
-- | The `Options` type represents a set of options. The type argument is a
-- | phantom type, which is useful for ensuring that options for one particular
-- | API are not accidentally passed to some other API.
newtype Options opt =
Options (Array (Tuple String Foreign))

import Data.Monoid (Monoid)
runOptions :: forall opt. Options opt -> Array (Tuple String Foreign)
runOptions (Options xs) = xs

import Data.Tuple (Tuple(..))
instance semigroupOptions :: Semigroup (Options opt) where
append (Options xs) (Options ys) = Options (xs <> ys)

import Unsafe.Coerce (unsafeCoerce)
instance monoidOptions :: Monoid (Options opt) where
mempty = Options []

foreign import data Options :: * -> *
-- | Convert an `Options` value into a JavaScript object, suitable for passing
-- | to JavaScript APIs.
options :: forall opt. Options opt -> Foreign
options = toForeign <<< StrMap.fromFoldable <<< runOptions

foreign import data Option :: * -> * -> *
-- | An `Option` represents an opportunity to configure a specific attribute
-- | of a call to some API. This normally corresponds to one specific property
-- | of an "options" object in JavaScript APIs, but can in general correspond
-- | to zero or more actual properties.
type Option opt = Op (Options opt)

class IsOption value where
assoc :: forall opt. Option opt value -> value -> Options opt
-- | Associates a value with a specific option.
assoc :: forall opt value. Option opt value -> value -> Options opt
assoc o value = runOp o value

infixr 6 :=

(:=) :: forall opt value. (IsOption value) => Option opt value -> value -> Options opt
-- | An infix version of `assoc`.
(:=) :: forall opt value. Option opt value -> value -> Options opt
(:=) = assoc

instance semigroupOptions :: Semigroup (Options a) where
append = runFn2 appendFn

instance monoidOptions :: Monoid (Options a) where
mempty = memptyFn

instance isOptionString :: IsOption String where
assoc = runFn2 isOptionPrimFn

instance isOptionBoolean :: IsOption Boolean where
assoc = runFn2 isOptionPrimFn

instance isOptionNumber :: IsOption Number where
assoc = runFn2 isOptionPrimFn

instance isOptionInt :: IsOption Int where
assoc = runFn2 isOptionPrimFn

instance isOptionRecord :: IsOption { | a } where
assoc = runFn2 isOptionPrimFn

instance isOptionUnit :: IsOption Unit where
assoc = runFn2 isOptionPrimFn

instance isOptionFunction :: IsOption (a -> b) where
assoc = runFn2 isOptionPrimFn

instance isOptionArray :: (IsOption a) => IsOption (Array a) where
assoc k vs = joinFn $ assoc (optionFn k) <$> vs

instance isOptionMaybe :: (IsOption a) => IsOption (Maybe a) where
assoc k Nothing = memptyFn
assoc k (Just a) = assoc (optionFn k) a

optionFn :: forall opt from to. Option opt from -> Option opt to
optionFn = unsafeCoerce

key :: forall opt value. Option opt value -> String
key = unsafeCoerce

opt :: forall opt value. (IsOption value) => String -> Option opt value
opt = unsafeCoerce

runOptions :: forall a. Options a -> Array (Tuple String Foreign)
runOptions = runOptionsFn Tuple

foreign import memptyFn :: forall a. Options a

foreign import appendFn :: forall a. Fn2 (Options a) (Options a) (Options a)

foreign import joinFn :: forall a b. Array (Options a) -> Options b

foreign import isOptionPrimFn :: forall b a. Fn2 (Option b a) a (Options b)

foreign import options :: forall a. Options a -> Foreign

foreign import runOptionsFn :: forall a. (String -> Foreign -> Tuple String Foreign) -> Options a -> Array (Tuple String Foreign)
-- | A version of `assoc` which takes possibly absent values. `Nothing` values
-- | are ignored; passing `Nothing` for the second argument will result in an
-- | empty `Options`.
optional :: forall opt value. Option opt value -> Option opt (Maybe value)
optional option = Op $ maybe mempty (option :=)

-- | The default way of creating `Option` values. Constructs an `Option` with
-- | the given key, which passes the given value through unchanged.
opt :: forall opt value. String -> Option opt value
opt = Op <<< defaultToOptions

-- | Create a `tag`, by fixing an `Option` to a single value.
tag :: forall opt value. Option opt value -> value -> Option opt Unit
tag o value = Op \_ -> o := value

-- | The default method for turning a string property key into an
-- | `Option`. This function simply calls `toForeign` on the value. If
-- | you need some other behaviour, you can write your own function to replace
-- | this one, and construct an `Option` yourself.
defaultToOptions :: forall opt value. String -> value -> Options opt
defaultToOptions k v = Options [Tuple k (toForeign v)]
Loading