fresnel-0.1.0.0: src/Fresnel/Semigroup/Fork1.hs
{-# LANGUAGE RankNTypes #-}
module Fresnel.Semigroup.Fork1
( -- * Non-empty binary trees
Fork1(..)
-- * Construction
, singleton
) where
import Data.Foldable (toList)
import Data.Foldable1
import Data.Functor.Alt
-- Non-empty binary trees
newtype Fork1 a = Fork1 { runFork1 :: forall r . (r -> r -> r) -> (a -> r) -> r }
instance Show a => Show (Fork1 a) where
showsPrec _ = showList . toList
instance Semigroup (Fork1 a) where
Fork1 a1 <> Fork1 a2 = Fork1 (\ (<>) singleton -> a1 (<>) singleton <> a2 (<>) singleton)
instance Foldable Fork1 where
foldMap = foldMap1
instance Foldable1 Fork1 where
foldMap1 f (Fork1 r) = r (<>) f
instance Functor Fork1 where
fmap f (Fork1 r) = Fork1 (\ (<>) singleton -> r (<>) (singleton . f))
instance Traversable Fork1 where
traverse f (Fork1 r) = r ((<*>) . fmap (<>)) (fmap singleton . f)
instance Apply Fork1 where
liftF2 f (Fork1 a) (Fork1 b) = Fork1 (\ (<>) singleton -> a (<>) (\ a' -> b (<>) (singleton . f a')))
instance Applicative Fork1 where
pure = singleton
(<*>) = (<.>)
instance Alt Fork1 where
(<!>) = (<>)
-- Construction
singleton :: a -> Fork1 a
singleton a = Fork1 (\ _ singleton -> singleton a)