Skip to content

Introduce purs-tidy formatter #34

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 7 commits into from
Nov 17, 2021
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
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:

- name: Set up a PureScript toolchain
uses: purescript-contrib/setup-purescript@main
with:
purs-tidy: "latest"

- name: Cache PureScript dependencies
uses: actions/cache@v2
Expand All @@ -32,3 +34,6 @@ jobs:

- name: Run tests
run: spago test --no-install

- name: Check formatting
run: purs-tidy check src test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
!.gitignore
!.github
!.editorconfig
!.tidyrc.json

output
generated-docs
Expand Down
10 changes: 10 additions & 0 deletions .tidyrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"importSort": "source",
"importWrap": "source",
"indent": 2,
"operatorsFile": null,
"ribbon": 1,
"typeArrowPlacement": "first",
"unicode": "never",
"width": null
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ New features:
Bugfixes:

Other improvements:
- Added `purs-tidy` formatter (#34 by @thomashoneyman)

## [v6.0.0](https://github.com/purescript-contrib/purescript-freet/releases/tag/v6.0.0) - 2021-02-26

Expand Down
50 changes: 24 additions & 26 deletions src/Control/Comonad/Cofree/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ newtype CofreeT f w a = CofreeT (Unit -> w (Tuple a (f (CofreeT f w a))))

-- | Construct a `CofreeT` from a lazy computation with an annotation 'a'.
cofreeT
:: forall f w a
. (Unit -> w (Tuple a (f (CofreeT f w a))))
-> CofreeT f w a
:: forall f w a
. (Unit -> w (Tuple a (f (CofreeT f w a))))
-> CofreeT f w a
cofreeT = CofreeT

-- | Construct a `CofreeT` from a computation with an annotation 'a'.
cofreeT'
:: forall f w a
. w (Tuple a (f (CofreeT f w a)))
-> CofreeT f w a
cofreeT' t = CofreeT $ (\_ -> t)
:: forall f w a
. w (Tuple a (f (CofreeT f w a)))
-> CofreeT f w a
cofreeT' t = CofreeT (\_ -> t)

-- | Unpack `CofreeT` into the inner computation.
runCofreeT :: forall f w a. CofreeT f w a -> w (Tuple a (f (CofreeT f w a)))
Expand All @@ -63,41 +63,39 @@ instance functorCofreeT :: (Functor w, Functor f) => Functor (CofreeT f w) where

instance applyCofreeT :: (Apply w, Apply f) => Apply (CofreeT f w) where
apply (CofreeT innerF) (CofreeT inner) =
CofreeT
$ \_ ->
go <$> innerF unit <*> inner unit
CofreeT $ \_ ->
go <$> innerF unit <*> inner unit
where
go (Tuple f nextF) (Tuple x nextX) =
Tuple (f x) (lift2 (<*>) nextF nextX)
go (Tuple f nextF) (Tuple x nextX) =
Tuple (f x) (lift2 (<*>) nextF nextX)

instance applicativeCofreeT :: (Applicative w, Apply f, Plus f) => Applicative (CofreeT f w) where
pure a = CofreeT $ \_ -> pure (Tuple a empty)

instance bindCofreeT :: (Monad w, Alt f, Apply f) => Bind (CofreeT f w) where
bind (CofreeT inner) f =
CofreeT
$ \_ -> do
(Tuple a m) <- inner unit
let (CofreeT next) = f a
(Tuple b n) <- next unit
pure $ Tuple b (n <|> map (_ >>= f) m)
CofreeT $ \_ -> do
(Tuple a m) <- inner unit
let (CofreeT next) = f a
(Tuple b n) <- next unit
pure $ Tuple b (n <|> map (_ >>= f) m)

instance monadCofreeT :: (Monad w, Plus f, Apply f) => Monad (CofreeT f w)

instance monadTransCofreeT :: Plus f => MonadTrans (CofreeT f) where
lift = cofreeT' <<< map go
where
go x = Tuple x empty
go x = Tuple x empty

instance monadEffectCofreeT :: (MonadEffect w, Plus f, Apply f) => MonadEffect (CofreeT f w) where
liftEffect eff = cofreeT' $ go <$> liftEffect eff
where
go a = Tuple a empty
go a = Tuple a empty

instance monadAffCofreeT :: (MonadAff w, Plus f, Apply f) => MonadAff (CofreeT f w) where
liftAff aff = cofreeT' $ go <$> liftAff aff
where
go a = Tuple a empty
go a = Tuple a empty

instance comonadCofreeCofreeT :: (Comonad w, Functor f) => ComonadCofree f (CofreeT f w) where
unwrapCofree = extract <<< tail
Expand All @@ -111,7 +109,7 @@ instance comonadAskCofreeT :: (Functor f, ComonadAsk e w) => ComonadAsk e (Cofre
instance foldableCofreeT :: (Foldable w, Foldable f) => Foldable (CofreeT f w) where
foldMap f (CofreeT inner) = foldMap go $ inner unit
where
go (Tuple a next) = f a <> foldMap (foldMap f) next
go (Tuple a next) = f a <> foldMap (foldMap f) next

foldr abb b = foldrDefault abb b

Expand All @@ -121,14 +119,14 @@ instance traversableCofreeT :: (Traversable w, Traversable f) => Traversable (Co
traverse f (CofreeT inner) =
cofreeT' <$> traverse go (inner unit)
where
go (Tuple a next) = Tuple <$> f a <*> traverse (traverse f) next
go (Tuple a next) = Tuple <$> f a <*> traverse (traverse f) next

sequence = sequenceDefault

instance extendCofreeT :: (Comonad w, Functor f) => Extend (CofreeT f w) where
extend f (CofreeT inner) = CofreeT $ \_ -> extend go (inner unit)
where
go w = Tuple (f $ cofreeT' w) $ extend f <$> T.snd (extract w)
go w = Tuple (f $ cofreeT' w) $ extend f <$> T.snd (extract w)

instance comonadCofreeT :: (Comonad w, Functor f) => Comonad (CofreeT f w) where
extract = extract <<< head
Expand All @@ -145,5 +143,5 @@ interpretCofreeT nf = bimapCofreeT nf identity
bimapCofreeT :: forall f g w u a. Functor u => Functor g => (f ~> g) -> (w ~> u) -> CofreeT f w a -> CofreeT g u a
bimapCofreeT nf nm (CofreeT inner) = CofreeT $ (map (map (map go))) $ map nm inner
where
go :: f (CofreeT f w a) -> g (CofreeT g u a)
go = map (bimapCofreeT nf nm) <<< nf
go :: f (CofreeT f w a) -> g (CofreeT g u a)
go = map (bimapCofreeT nf nm) <<< nf
19 changes: 10 additions & 9 deletions src/Control/Monad/Free/Trans.purs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,16 @@ resume = tailRecM go
where
go :: FreeT f m a -> m (Step (FreeT f m a) (Either a (f (FreeT f m a))))
go (FreeT f) = map Done (f unit)
go (Bind e) = runExists (\(Bound bound' f) ->
case bound' unit of
FreeT m ->
m unit >>= case _ of
Left a -> pure (Loop (f a))
Right fc -> pure (Done (Right (map (\h -> h >>= f) fc)))
Bind e1 -> runExists (\(Bound m1 f1) -> pure (Loop (bind (m1 unit) (\z -> f1 z >>= f)))) e1) e
go (Bind e) =
e # runExists \(Bound bound' f) ->
case bound' unit of
FreeT m ->
m unit >>= case _ of
Left a -> pure (Loop (f a))
Right fc -> pure (Done (Right (map (\h -> h >>= f) fc)))
Bind e1 ->
e1 # runExists \(Bound m1 f1) ->
pure (Loop (bind (m1 unit) (\z -> f1 z >>= f)))

instance functorFreeT :: (Functor f, Functor m) => Functor (FreeT f m) where
map f (FreeT m) = FreeT \_ -> map (bimap f (map (map f))) (m unit)
Expand Down Expand Up @@ -126,7 +129,6 @@ bimapFreeT :: forall f g m n a. Functor f => Functor n => (f ~> g) -> (m ~> n) -
bimapFreeT nf nm (Bind e) = runExists (\(Bound a f) -> bound (bimapFreeT nf nm <<< a) (bimapFreeT nf nm <<< f)) e
bimapFreeT nf nm (FreeT m) = FreeT \_ -> map (nf <<< map (bimapFreeT nf nm)) <$> nm (m unit)


-- | Like `runFreeT`, but for running into some other FreeT without the
-- | overhead that `MonadRec` incurs.
substFreeT :: forall a m f g. Monad m => Functor g => (f ~> FreeT g m) -> FreeT f m a -> FreeT g m a
Expand All @@ -135,7 +137,6 @@ substFreeT fBind (FreeT m) = join $ FreeT \_ -> m unit <#> case _ of
Left val -> Left $ pure val
Right fFree -> Left $ bound (\_ -> fBind fFree) (substFreeT fBind)


-- | Run a `FreeT` computation to completion.
runFreeT :: forall f m a. Functor f => MonadRec m => (f (FreeT f m a) -> m (FreeT f m a)) -> FreeT f m a -> m a
runFreeT interp = tailRecM (go <=< resume)
Expand Down
8 changes: 4 additions & 4 deletions test/CofreeTExample.purs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ type IndexedList = CofreeT List Maybe Int
list :: IndexedList
list = cofreeT (go 5)
where
go :: Int -> Unit -> Maybe (Tuple Int (List IndexedList))
go 0 _ = Just $ Tuple 0 Nil
go 5 _ = Just $ Tuple 5 (fromFoldable $ cofreeT <$> (go <$> [4, 3]))
go i _ = Just $ Tuple i (pure $ cofreeT (go (i - 1)))
go :: Int -> Unit -> Maybe (Tuple Int (List IndexedList))
go 0 _ = Just $ Tuple 0 Nil
go 5 _ = Just $ Tuple 5 (fromFoldable $ cofreeT <$> (go <$> [ 4, 3 ]))
go i _ = Just $ Tuple i (pure $ cofreeT (go (i - 1)))

annotations :: IndexedList -> List (Maybe Int)
annotations il = head il : join (annotations <$> fromMaybe mempty (tail il))
Expand Down
3 changes: 2 additions & 1 deletion test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ mockTeletype = runFreeT interp

-- Also see purescript-safely
replicateM_ :: forall m a. MonadRec m => Int -> m a -> m Unit
replicateM_ n x = tailRecM step n where
replicateM_ n x = tailRecM step n
where
step :: Int -> m (Step Int Unit)
step 0 = pure (Done unit)
step m = x $> Loop (m - 1)
Expand Down