Skip to content

Add fromNonEmpty operation #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 13, 2015
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
10 changes: 3 additions & 7 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
{
"name": "purescript-nonempty",
"version": "1.0.0",
"moduleType": [
"node"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"output"
],
"repository": {
"type": "git",
"url": "git://github.com/paf31/purescript-nonempty.git"
"repository": {
"type": "git",
"url": "git://github.com/paf31/purescript-nonempty.git"
},
"dependencies": {
"purescript-console": "^0.1.0",
Expand Down
14 changes: 13 additions & 1 deletion docs/Data/NonEmpty.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Fold a non-empty structure, collecting results using a binary operation.
foldMap1 :: forall f a s. (Semigroup s, Foldable f) => (a -> s) -> NonEmpty f a -> s
```

Fold a non-empty structure, collecting results in a `Semigroup`.
Fold a non-empty structure, collecting results in a `Semigroup`.

#### `fold1`

Expand All @@ -63,4 +63,16 @@ fold1 :: forall f s. (Semigroup s, Foldable f) => NonEmpty f s -> s

Fold a non-empty structure.

#### `fromNonEmpty`

``` purescript
fromNonEmpty :: forall f a r. (a -> f a -> r) -> NonEmpty f a -> r
```

#### `oneOf`

``` purescript
oneOf :: forall f a. (Alternative f) => NonEmpty f a -> f a
```


27 changes: 19 additions & 8 deletions src/Data/NonEmpty.purs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
-- | This module defines a generic non-empty data structure, which adds an additional
-- | element to any container type.

module Data.NonEmpty
module Data.NonEmpty
( NonEmpty(..)
, (:|)
, foldl1
, foldMap1
, fold1
, fromNonEmpty
, oneOf
) where

import Prelude

import Data.Foldable
import Data.Traversable
import Control.Alternative (Alternative)
import Control.Alt ((<|>))

import Data.Foldable (Foldable, foldl, foldr, foldMap)
import Data.Traversable (Traversable, traverse, sequence)

-- | A non-empty container of elements of type a.
-- |
Expand All @@ -34,34 +39,40 @@ infix 5 :|
foldl1 :: forall f a s. (Foldable f) => (a -> a -> a) -> NonEmpty f a -> a
foldl1 f (NonEmpty a fa) = foldl f a fa

-- | Fold a non-empty structure, collecting results in a `Semigroup`.
-- | Fold a non-empty structure, collecting results in a `Semigroup`.
foldMap1 :: forall f a s. (Semigroup s, Foldable f) => (a -> s) -> NonEmpty f a -> s
foldMap1 f (NonEmpty a fa) = foldl (\s a1 -> s <> f a1) (f a) fa

-- | Fold a non-empty structure.
fold1 :: forall f s. (Semigroup s, Foldable f) => NonEmpty f s -> s
fold1 = foldMap1 id

fromNonEmpty :: forall f a r. (a -> f a -> r) -> NonEmpty f a -> r
fromNonEmpty f (NonEmpty a fa) = a `f` fa

oneOf :: forall f a. (Alternative f) => NonEmpty f a -> f a
oneOf (NonEmpty a fa) = pure a <|> fa

instance showNonEmpty :: (Show a, Show (f a)) => Show (NonEmpty f a) where
show (NonEmpty a fa) = "(NonEmpty " ++ show a ++ " " ++ show fa ++ ")"

instance eqNonEmpty :: (Eq a, Eq (f a)) => Eq (NonEmpty f a) where
eq (NonEmpty a1 fa1) (NonEmpty a2 fa2) = a1 == a2 && fa1 == fa2

instance ordNonEmpty :: (Ord a, Ord (f a)) => Ord (NonEmpty f a) where
compare (NonEmpty a1 fa1) (NonEmpty a2 fa2) =
compare (NonEmpty a1 fa1) (NonEmpty a2 fa2) =
case compare a1 a2 of
EQ -> compare fa1 fa2
other -> other

instance functorNonEmpty :: (Functor f) => Functor (NonEmpty f) where
map f (NonEmpty a fa) = NonEmpty (f a) (map f fa)

instance foldableNonEmpty :: (Foldable f) => Foldable (NonEmpty f) where
foldMap f (NonEmpty a fa) = f a <> foldMap f fa
foldl f b (NonEmpty a fa) = foldl f (f b a) fa
foldr f b (NonEmpty a fa) = f a (foldr f b fa)

instance traversableNonEmpty :: (Traversable f) => Traversable (NonEmpty f) where
sequence (NonEmpty a fa) = NonEmpty <$> a <*> sequence fa
traverse f (NonEmpty a fa) = NonEmpty <$> f a <*> traverse f fa