mirror of
https://github.com/zap-proto/haskell.git
synced 2026-10-30 15:05:00 +00:00
The previous pass was racy; it could result in sending the finish message before the disembargo in various scenarios. I *think* this solves the problem, but need to test. This might still take some tweak to expose to the typed layer.
49 lines
1.3 KiB
Haskell
49 lines
1.3 KiB
Haskell
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
|
module Internal.SnocList
|
|
( SnocList
|
|
, fromList
|
|
, empty
|
|
, snoc
|
|
, singleton
|
|
) where
|
|
|
|
import Data.Foldable
|
|
import Data.Hashable (Hashable)
|
|
|
|
-- | A 'SnocList' is just a list, but with efficient appending instead of
|
|
-- prepending. The indended use case is when you want to append a bunch of
|
|
-- things to a list, and then get the final list to work with.
|
|
--
|
|
-- A standard trick for this is to cons each element onto the *front* of
|
|
-- the list, and then reverse the list before processing. A SnocList
|
|
-- just packages up this trick so you can't forget to do the reverse.
|
|
newtype SnocList a = SnocList [a]
|
|
deriving(Eq, Hashable)
|
|
|
|
-- | Convert a list to a 'SnocList'. O(n)
|
|
fromList :: [a] -> SnocList a
|
|
fromList = SnocList . reverse
|
|
|
|
-- | A one-element 'SnocList'.
|
|
singleton :: a -> SnocList a
|
|
singleton x = SnocList [x]
|
|
|
|
-- | The empty 'SnocList'.
|
|
empty :: SnocList a
|
|
empty = SnocList []
|
|
|
|
-- | Append a value to the 'SnocList'. A note on the name: 'snoc' is @cons@
|
|
-- backwards.
|
|
snoc :: SnocList a -> a -> SnocList a
|
|
snoc (SnocList xs) x = SnocList (x:xs)
|
|
|
|
instance Foldable SnocList where
|
|
foldMap f = foldMap f . toList
|
|
toList (SnocList xs) = reverse xs
|
|
|
|
instance Semigroup (SnocList a) where
|
|
(SnocList l) <> (SnocList r) = SnocList (r <> l)
|
|
|
|
instance Monoid (SnocList a) where
|
|
mempty = empty
|