Skip to content

Commit

Permalink
Added docs
Browse files Browse the repository at this point in the history
  • Loading branch information
zudov committed Sep 16, 2015
1 parent 35bb017 commit 6a97d1b
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# purescript-var

An API to provide uniform read/write access to the references in the `Eff` monad.
3 changes: 3 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@
"purescript-eff": "~0.1.0",
"purescript-contravariant": "~0.2.1",
"purescript-invariant": "~0.3.0"
},
"devDependencies": {
"purescript-console": "~0.1.1"
}
}
160 changes: 160 additions & 0 deletions docs/Control/Monad/Eff/Var.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
## Module Control.Monad.Eff.Var

`Var`s allow to provide a uniform read/write access to the references in
the `Eff` monad. This is mostly useful when making low-level FFI bindings.
For example we might have some global counter with the following API:
```purescript
foreign import data COUNT :: !
getCounter :: forall eff. Eff (count :: COUNT | eff) Int
setCounter :: forall eff. Int -> Eff (count :: COUNT | eff) Unit
```

`getCounter` and `setCounter` can be kept together in a `Var`:
```purescript
counter :: forall eff. Var (count :: COUNT | eff) Int
counter = makeVar getCounter setCounter
```

`counter` can be used in this way:
```purescript
main = do
counter $= 0 -- set counter to 0
get counter >>= print -- => 0
counter $= 2 -- set counter to 2
get counter >>= print -- => 2
counter $~ (* 5) -- multiply counter by 5
get counter >>= print -- => 10
```

#### `Gettable`

``` purescript
class Gettable (eff :: # !) (var :: * -> *) (a :: *) where
get :: var a -> Eff eff a
```

Typeclass for vars that can be read.

##### Instances
``` purescript
instance gettableVar :: Gettable eff (Var eff) a
instance gettableGettableVar :: Gettable eff (GettableVar eff) a
```

#### `Settable`

``` purescript
class Settable (eff :: # !) (var :: * -> *) (a :: *) where
set :: var a -> a -> Eff eff Unit
```

Typeclass for vars that can be written.

##### Instances
``` purescript
instance settableVar :: Settable eff (Var eff) a
instance settableSettableVar :: Settable eff (SettableVar eff) a
```

#### `($=)`

``` purescript
($=) :: forall eff var a. (Settable eff var a) => var a -> a -> Eff eff Unit
```

_right-associative / precedence 2_

#### `Updatable`

``` purescript
class Updatable (eff :: # !) (var :: * -> *) (a :: *) where
update :: var a -> (a -> a) -> Eff eff Unit
```

Typeclass for vars that can be updated.

##### Instances
``` purescript
instance updatableVar :: Updatable eff (Var eff) a
```

#### `($~)`

``` purescript
($~) :: forall eff var a. (Updatable eff var a) => var a -> (a -> a) -> Eff eff Unit
```

_right-associative / precedence 2_

#### `Var`

``` purescript
data Var (eff :: # !) a
```

Read/Write var which holds a value of type `a` and produces effects `eff`
when read or written.

##### Instances
``` purescript
instance settableVar :: Settable eff (Var eff) a
instance gettableVar :: Gettable eff (Var eff) a
instance updatableVar :: Updatable eff (Var eff) a
instance invariantVar :: Invariant (Var eff)
```

#### `makeVar`

``` purescript
makeVar :: forall eff a. Eff eff a -> (a -> Eff eff Unit) -> Var eff a
```

Create a `Var` from getter and setter.

#### `GettableVar`

``` purescript
newtype GettableVar eff a
```

Read-only var which holds a value of type `a` and produces effects `eff`
when read.

##### Instances
``` purescript
instance gettableGettableVar :: Gettable eff (GettableVar eff) a
instance functorGettableVar :: Functor (GettableVar eff)
```

#### `makeGettableVar`

``` purescript
makeGettableVar :: forall eff a. Eff eff a -> GettableVar eff a
```

Create a `GettableVar` from getter.

#### `SettableVar`

``` purescript
newtype SettableVar eff a
```

Write-only var which holds a value of type `a` and produces effects `eff`
when written.

##### Instances
``` purescript
instance settableSettableVar :: Settable eff (SettableVar eff) a
instance contravariantSettableVar :: Contravariant (SettableVar eff)
```

#### `makeSettableVar`

``` purescript
makeSettableVar :: forall eff a. (a -> Eff eff Unit) -> SettableVar eff a
```

Create a `SettableVar` from setter.


42 changes: 42 additions & 0 deletions src/Control/Monad/Eff/Var.purs
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
-- | `Var`s allow to provide a uniform read/write access to the references in
-- | the `Eff` monad. This is mostly useful when making low-level FFI bindings.

-- | For example we might have some global counter with the following API:
-- | ```purescript
-- | foreign import data COUNT :: !
-- | getCounter :: forall eff. Eff (count :: COUNT | eff) Int
-- | setCounter :: forall eff. Int -> Eff (count :: COUNT | eff) Unit
-- | ```
-- |
-- | `getCounter` and `setCounter` can be kept together in a `Var`:
-- | ```purescript
-- | counter :: forall eff. Var (count :: COUNT | eff) Int
-- | counter = makeVar getCounter setCounter
-- | ```
-- |
-- | `counter` can be used in this way:
-- | ```purescript
-- | main = do
-- | counter $= 0 -- set counter to 0
-- | get counter >>= print -- => 0
-- | counter $= 2 -- set counter to 2
-- | get counter >>= print -- => 2
-- | counter $~ (* 5) -- multiply counter by 5
-- | get counter >>= print -- => 10
-- | ```

module Control.Monad.Eff.Var
( Gettable
, get
Expand All @@ -18,30 +45,39 @@ module Control.Monad.Eff.Var
import Prelude

import Control.Monad.Eff
import Control.Monad.Eff.Ref
import Data.Functor.Contravariant
import Data.Functor.Invariant

-- | Typeclass for vars that can be read.
class Gettable (eff :: # !) (var :: * -> *) (a :: *) where
get :: var a -> Eff eff a

-- | Typeclass for vars that can be written.
class Settable (eff :: # !) (var :: * -> *) (a :: *) where
set :: var a -> a -> Eff eff Unit

-- | Alias for `set`.
infixr 2 $=
($=) :: forall eff var a. (Settable eff var a)
=> var a -> a -> Eff eff Unit
($=) = set

-- | Typeclass for vars that can be updated.
class Updatable (eff :: # !) (var :: * -> *) (a :: *) where
update :: var a -> (a -> a) -> Eff eff Unit

-- | Alias for `get`
infixr 2 $~
($~) :: forall eff var a. (Updatable eff var a)
=> var a -> (a -> a) -> Eff eff Unit
($~) = update

-- | Read/Write var which holds a value of type `a` and produces effects `eff`
-- | when read or written.
data Var (eff :: # !) a = Var (GettableVar eff a) (SettableVar eff a)

-- | Create a `Var` from getter and setter.
makeVar :: forall eff a. Eff eff a -> (a -> Eff eff Unit) -> Var eff a
makeVar g s = Var (makeGettableVar g) (makeSettableVar s)

Expand All @@ -57,8 +93,11 @@ instance updatableVar :: Updatable eff (Var eff) a where
instance invariantVar :: Invariant (Var eff) where
imap ab ba (Var ga sa) = Var (ab <$> ga) (ba >$< sa)

-- | Read-only var which holds a value of type `a` and produces effects `eff`
-- | when read.
newtype GettableVar eff a = GettableVar (Eff eff a)

-- | Create a `GettableVar` from getter.
makeGettableVar :: forall eff a. Eff eff a -> GettableVar eff a
makeGettableVar = GettableVar

Expand All @@ -68,8 +107,11 @@ instance gettableGettableVar :: Gettable eff (GettableVar eff) a where
instance functorGettableVar :: Functor (GettableVar eff) where
map f (GettableVar a) = GettableVar (f <$> a)

-- | Write-only var which holds a value of type `a` and produces effects `eff`
-- | when written.
newtype SettableVar eff a = SettableVar (a -> Eff eff Unit)

-- | Create a `SettableVar` from setter.
makeSettableVar :: forall eff a. (a -> Eff eff Unit) -> SettableVar eff a
makeSettableVar = SettableVar

Expand Down

0 comments on commit 6a97d1b

Please sign in to comment.