Skip to content
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

Add more instances, mostly Read and Ord #39

Merged
merged 5 commits into from
Mar 26, 2024
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
19 changes: 11 additions & 8 deletions .config/mustache.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{"project":{
"description":"Total recursion scheme library for Haskell.",
"name":"yaya",
"repo":"sellout/yaya",
"summary":"Yet another … yet another recursion scheme library for Haskell",
"version":"0.1.0.0"},
"type":{"name":"haskell"}
}
{
"project":
{
"description": "Total recursion scheme library for Haskell.",
"name": "yaya",
"repo": "sellout/yaya",
"summary": "Yet another … yet another recursion scheme library for Haskell",
"version": "0.1.0.0",
},
"type": { "name": "haskell" },
}
24 changes: 20 additions & 4 deletions .config/project/github-ci.nix
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,16 @@ in {
cabal-version = pkgs.cabal-install.version;
};
}
{run = "cabal install cabal-plan-bounds";}
{
run = ''
## TODO: Remove the manual cloning once cabal-plan-bounds >0.1.5.1
## is released. Currently, it’s needed because of
## nomeata/cabal-plan-bounds#19.
git clone https://github.com/nomeata/cabal-plan-bounds
cd cabal-plan-bounds
cabal install cabal-plan-bounds
'';
}
{
name = "download Cabal plans";
uses = "actions/download-artifact@v4";
Expand All @@ -113,9 +122,16 @@ in {
## TODO: Simplify this once cabal-plan-bounds supports a `--check`
## option.
run = ''
diffs="$(find . \
-name '*.cabal' \
-exec cabal-plan-bounds --dry-run plans/*.json --cabal {} \;)"
diffs="$(find . -name '*.cabal' -exec \
cabal-plan-bounds \
--dry-run \
${
lib.concatMapStrings
(pkg: "--also " + pkg + " ")
self.lib.extraDependencyVersions
} \
plans/*.json \
--cabal {} \;)"
if [[ -n "$diffs" ]]; then
echo "$diffs"
exit 1
Expand Down
97 changes: 83 additions & 14 deletions .config/project/hlint.nix
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
{lib, pkgs, ...}: {
{
lib,
pkgs,
...
}: {
## Haskell linter
programs.treefmt.programs.hlint.enable = true;
## TODO: Wrap this to find our generated hlint config in the store.
project.devPackages = [pkgs.hlint];
project.file.".hlint.yaml".text = lib.generators.toYAML {} [
{group = {name = "dollar"; enabled = true;};}
{group = {name = "future"; enabled = true;};}
{group = {name = "generalise"; enabled = true;};}
{
group = {
name = "dollar";
enabled = true;
};
}
{
group = {
name = "future";
enabled = true;
};
}
{
group = {
name = "generalise";
enabled = true;
};
}

{ignore = {name = "Eta reduce";};}
{ignore = {name = "Evaluate";};}
Expand Down Expand Up @@ -39,14 +58,54 @@
"package traversable"
];
rules = [
{warn = {lhs = "forM"; rhs = "for";};}
{warn = {lhs = "forM_"; rhs = "for_";};}
{warn = {lhs = "map"; rhs = "fmap";};}
{warn = {lhs = "mapM"; rhs = "traverse";};}
{warn = {lhs = "mapM_"; rhs = "traverse_";};}
{warn = {lhs = "return"; rhs = "pure";};}
{warn = {lhs = "sequence"; rhs = "sequenceA";};}
{warn = {lhs = "sequence_"; rhs = "sequenceA_";};}
{
warn = {
lhs = "forM";
rhs = "for";
};
}
{
warn = {
lhs = "forM_";
rhs = "for_";
};
}
{
warn = {
lhs = "map";
rhs = "fmap";
};
}
{
warn = {
lhs = "mapM";
rhs = "traverse";
};
}
{
warn = {
lhs = "mapM_";
rhs = "traverse_";
};
}
{
warn = {
lhs = "return";
rhs = "pure";
};
}
{
warn = {
lhs = "sequence";
rhs = "sequenceA";
};
}
{
warn = {
lhs = "sequence_";
rhs = "sequenceA_";
};
}
];
};
}
Expand All @@ -63,8 +122,18 @@
note = "IncreasesLaziness";
};
}
{warn = {lhs = "mappend"; rhs = "(<>)";};}
{warn = {lhs = "(++)"; rhs = "(<>)";};}
{
warn = {
lhs = "mappend";
rhs = "(<>)";
};
}
{
warn = {
lhs = "(++)";
rhs = "(<>)";
};
}
];
};
}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 70 additions & 20 deletions containers/src/Yaya/Containers/Pattern/IntMap.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE Safe #-}
{-# OPTIONS_GHC -Wno-orphans #-}

Expand All @@ -6,33 +7,53 @@ module Yaya.Containers.Pattern.IntMap
)
where

import "base" Control.Applicative (Alternative ((<|>)), Applicative ((<*>)), (*>))
import "base" Control.Category (Category ((.)))
import "base" Data.Bool (Bool (False, True), (&&))
import "base" Data.Eq (Eq ((==)))
import "base" Data.Foldable (Foldable)
import "base" Data.Function (($))
import "base" Data.Functor (Functor (fmap))
import "base" Data.Functor.Classes
( Eq1 (liftEq),
Eq2 (liftEq2),
Ord1 (liftCompare),
Ord2 (liftCompare2),
Show1 (liftShowsPrec),
Show2 (liftShowsPrec2),
)
import "base" Data.Functor (Functor (fmap), (<$), (<$>))
import "base" Data.Ord (Ord (compare, (<=)), Ordering (EQ, GT, LT))
import "base" Data.Semigroup ((<>))
import "base" Data.Traversable (Traversable)
import qualified "base" Data.Tuple as Tuple
import "base" GHC.Generics (Generic, Generic1)
import "base" Text.Show (Show (showList, showsPrec), showParen, showString)
import "base" GHC.Read (Read (readListPrec, readPrec), expectP, parens)
import "base" Text.ParserCombinators.ReadPrec (prec, step)
import qualified "base" Text.Read.Lex as Lex
import qualified "containers" Data.IntMap.Internal as IntMap
import "yaya" Yaya.Fold
( Projectable (project),
Recursive (cata),
Steppable (embed),
)
import "base" Prelude (Num ((+)))
#if MIN_VERSION_base(4, 18, 0)
import "base" Data.Functor.Classes
( Eq1,
Eq2 (liftEq2),
Ord2 (liftCompare2),
Ord1,
Read1 (liftReadPrec),
Read2 (liftReadPrec2),
Show1,
Show2 (liftShowsPrec2),
)
import "base" Text.Show (Show (showsPrec), showParen, showString)
#else
import "base" Data.Functor.Classes
( Eq1 (liftEq),
Eq2 (liftEq2),
Ord1 (liftCompare),
Ord2 (liftCompare2),
Read1 (liftReadPrec),
Read2 (liftReadPrec2),
Show1 (liftShowsPrec),
Show2 (liftShowsPrec2),
)
import "base" Text.Show (Show (showList, showsPrec), showParen, showString)
#endif

data IntMapF a r
= NilF
Expand All @@ -42,6 +63,8 @@ data IntMapF a r
( Eq,
Ord,
Generic,
-- | @since 0.1.2.0
Read,
Show,
Foldable,
Functor,
Expand All @@ -62,10 +85,12 @@ instance Steppable (->) (IntMap.IntMap a) (IntMapF a) where
embed (TipF key a) = IntMap.Tip key a
embed (BinF prefix mask l r) = IntMap.Bin prefix mask l r

#if MIN_VERSION_base(4, 18, 0)
instance (Eq a) => Eq1 (IntMapF a)
#else
instance (Eq a) => Eq1 (IntMapF a) where
-- TODO: Remove this once base-4.18 is the oldest supported verson, as it’s
-- the default impl.
liftEq = liftEq2 (==)
#endif

instance Eq2 IntMapF where
liftEq2 f g = Tuple.curry $ \case
Expand All @@ -75,10 +100,12 @@ instance Eq2 IntMapF where
prefix == prefix' && mask == mask' && g l l' && g r r'
(_, _) -> False

#if MIN_VERSION_base(4, 18, 0)
instance (Ord a) => Ord1 (IntMapF a)
#else
instance (Ord a) => Ord1 (IntMapF a) where
-- TODO: Remove this once base-4.18 is the oldest supported verson, as it’s
-- the default impl.
liftCompare = liftCompare2 compare
#endif

instance Ord2 IntMapF where
liftCompare2 f g = Tuple.curry $ \case
Expand All @@ -91,25 +118,48 @@ instance Ord2 IntMapF where
compare prefix prefix' <> compare mask mask' <> g l l' <> g r r'
(BinF {}, _) -> GT

-- | @since 0.1.2.0
instance (Read a) => Read1 (IntMapF a) where
liftReadPrec = liftReadPrec2 readPrec readListPrec

-- | @since 0.1.2.0
instance Read2 IntMapF where
liftReadPrec2 readPrecA _ readPrecR _ =
let appPrec = 10
in parens . prec appPrec $
NilF
<$ expectP (Lex.Ident "NilF")
<|> expectP (Lex.Ident "TipF")
*> (TipF <$> step readPrec <*> step readPrecA)
<|> expectP (Lex.Ident "BinF")
*> ( BinF
<$> step readPrec
<*> step readPrec
<*> step readPrecR
<*> step readPrecR
)

#if MIN_VERSION_base(4, 18, 0)
instance (Show a) => Show1 (IntMapF a)
#else
instance (Show a) => Show1 (IntMapF a) where
-- TODO: Remove this once base-4.18 is the oldest supported verson, as it’s
-- the default impl.
liftShowsPrec = liftShowsPrec2 showsPrec showList
#endif

instance Show2 IntMapF where
liftShowsPrec2 showsPrecA _showListA showsPrecR _showListR prec =
liftShowsPrec2 showsPrecA _ showsPrecR _ p =
let appPrec = 10
nextPrec = appPrec + 1
in \case
NilF -> showString "NilF"
TipF key a ->
showParen (nextPrec <= prec) $
showString "BipF "
showParen (nextPrec <= p) $
showString "TipF "
. showsPrec nextPrec key
. showString " "
. showsPrecA nextPrec a
BinF prefix mask l r ->
showParen (nextPrec <= prec) $
showParen (nextPrec <= p) $
showString "BinF "
. showsPrec nextPrec prefix
. showString " "
Expand Down
Loading
Loading