-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Semigroups, Monoids, Zips, and
AsRecord
(#13)
* Monoids, Semigroups, and Zips * AsRecord * tests * changelog, version bump * stylin * hmm
- Loading branch information
1 parent
afd73d0
commit c4fd756
Showing
8 changed files
with
178 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
-- | This module contains a newtype 'AsRecord' which is used to provide | ||
-- a variety of default instances for types based on their 'Record' | ||
-- instance. | ||
module Prairie.AsRecord where | ||
|
||
import Prairie.Class | ||
import Prairie.Monoid | ||
import Prairie.Semigroup | ||
|
||
-- | This @newtype@ is intended for use with @DerivingVia@. | ||
-- | ||
-- For an example use, let's consider this @User@ datatype: | ||
-- | ||
-- > data Foo = Foo | ||
-- > { ints :: [Int] | ||
-- > , char :: First Char | ||
-- > } | ||
-- > | ||
-- > mkRecord ''Foo | ||
-- | ||
-- Let's say we want to define an instance of 'Semigroup' for this type, so | ||
-- that we can combine two of them. Ordinarily, we'd need to write | ||
-- a boilerplate-y instance: | ||
-- | ||
-- > instance Semigroup Foo where | ||
-- > f0 <> f1 = Foo | ||
-- > { ints = f0.ints <> f1.ints | ||
-- > , char = f0.char <> f1.char | ||
-- > } | ||
-- | ||
-- With @DerivingVia@, we can use 'AsRecord' to provide it easily: | ||
-- | ||
-- @ | ||
-- deriving via AsRecord Foo instance Semigroup Foo | ||
-- @ | ||
-- | ||
-- @since 0.0.4.0 | ||
newtype AsRecord rec = AsRecord { unAsRecord :: rec } | ||
|
||
-- | | ||
-- | ||
-- @since 0.0.4.0 | ||
instance (Record rec, FieldDict Semigroup rec) => Semigroup (AsRecord rec) where | ||
AsRecord r0 <> AsRecord r1 = | ||
AsRecord (appendRecord r0 r1) | ||
|
||
-- | | ||
-- | ||
-- @since 0.0.4.0 | ||
instance (Record rec, FieldDict Semigroup rec, FieldDict Monoid rec) => Monoid (AsRecord rec) where | ||
mempty = AsRecord emptyRecord |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
module Prairie.Monoid where | ||
|
||
import Prairie.Class | ||
|
||
-- | Create a 'mempty' 'Record' assuming that all of the fields of the | ||
-- record have a 'Monoid' instance. | ||
-- | ||
-- @since 0.0.4.0 | ||
emptyRecord :: (Record rec, FieldDict Monoid rec) => rec | ||
emptyRecord = tabulateRecord (\field -> withFieldDict @Monoid field mempty) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
-- | This module provides the ability to append two records using '(<>)', | ||
-- provided that all of their fields have an instance of 'Semigroup'. | ||
module Prairie.Semigroup where | ||
|
||
import Prairie.Class | ||
import Prairie.Zip | ||
|
||
-- | Zip two records together using a 'Semigroup' append. | ||
-- | ||
-- @since 0.0.4.0 | ||
appendRecord | ||
:: forall rec. (Record rec, FieldDict Semigroup rec) | ||
=> rec | ||
-> rec | ||
-> rec | ||
appendRecord = | ||
zipWithRecord (\a b field -> withFieldDict @Semigroup field (a <> b)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
module Prairie.Zip where | ||
|
||
import Prairie.Class | ||
import Prairie.Fold | ||
|
||
-- | Take two records and zip them together with the provided function. | ||
-- | ||
-- The field is given for the final parameter in the function, allowing you to use @LambdaCase@. | ||
-- | ||
-- @ | ||
-- zipWithRecord | ||
-- (\a b -> | ||
-- \case | ||
-- UserName -> | ||
-- a <> b | ||
-- UserAge -> | ||
-- a + b | ||
-- ) | ||
-- @ | ||
-- | ||
-- @since 0.0.4.0 | ||
zipWithRecord | ||
:: forall rec. (Record rec) | ||
=> (forall ty. ty -> ty -> Field rec ty -> ty) | ||
-> rec | ||
-> rec | ||
-> rec | ||
zipWithRecord k r0 r1 = | ||
foldRecord f r0 r0 | ||
where | ||
f :: ty -> rec -> Field rec ty -> rec | ||
f v0 rec field = | ||
let v1 = getRecordField field r1 | ||
in setRecordField field (k v0 v1 field) rec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters