Ticket #12001
.
pattern Singleton :: a -> NonEmpty a
pattern Singleton a <- (uncons -> (a, Nothing))
where Singleton a = a N.:| []
infixr 5 :|
pattern (:|) :: a -> NonEmpty a -> NonEmpty a
pattern a:|as <- (uncons -> (a, Just as))
where a:|(a' N.:| as) = a N.:| a':as
matches inductive type
-- Control.Monad.Cofree.Cofree Maybe
data NonEmpty a = Singleton a | a :| NonEmpty a
Compare this to the solution using NonEmpty
-- gcd' :: GCDDomain r => NonEmpty r -> r
-- gcd' (x :| []) = normalize x
-- gcd' (x :| [y]) = gcd x y
-- gcd' (x :| NonEmpty ys) = gcd x (gcd' ys)
gcd' :: GCDDomain a => NonEmpty a -> a
gcd' (Singleton x) = normalize x
gcd' (x :| xs) = gcd x (gcd' xs)
-- unwrap (_ N.:| []) = Nothing
-- unwrap (_ N.:| NonEmpty as) = Just as
unwrap :: NonEmpty a -> Maybe (NonEmpty a)
unwrap Singleton{} = Nothing
unwrap (_:|as) = Just as
Maybe add a fold for good measure
foldNonEmpty :: NonEmpty a -> (a -> r) -> (a -> r -> r) -> r
foldNonEmpty (Singleton a) f _ = f a
foldNonEmpty (a:|as) f (·) = a · foldNonEmpty as f (·)
ghc' :: GCDDomain a => NonEmpty a -> a
gcd' = foldNonEmpty normalize ghc