>>> some (putStr "la") lalalalalalalalala... * goes on forever *
>>> some Nothing nothing
>>> take 5 <$> some (Just 1) * hangs forever *Note that this function can be used with Parsers based on Applicatives. In that case some parser will attempt to parse parser one or more times until it fails.
word = some letter
word = some letter
word = some letter
>>> some p f = Parser.manyP p (Parser.takeGE 1 f) >>> some = Parser.countBetween 1 maxBoundCompare with some.
>>> data Tag :: Type -> Type where TagInt :: Tag Int; TagBool :: Tag Bool >>> instance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool" >>> classify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> [] >>> instance GRead Tag where greadsPrec _ s = [ (r, rest) | (con, rest) <- lex s, r <- classify con ]You can either use PatternSynonyms (available with GHC >= 8.0)
>>> let x = Some TagInt >>> x Some TagInt
>>> case x of { Some TagInt -> "I"; Some TagBool -> "B" } :: String "I"or you can use functions
>>> let y = mkSome TagBool >>> y Some TagBool
>>> withSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String "B"The implementation of mapSome is safe.
>>> let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool >>> mapSome f y Some TagBoolbut you can also use:
>>> withSome y (mkSome . f) Some TagBool
>>> read "Some TagBool" :: Some Tag Some TagBool
>>> read "mkSome TagInt" :: Some Tag Some TagInt
>>> data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Bool >>> instance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool" >>> classify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> [] >>> instance GRead Tag where greadsPrec _ s = [ (r, rest) | (con, rest) <- lex s, r <- classify con ]With Church-encoding youcan only use a functions:
>>> let y = mkSome TagBool >>> y mkSome TagBool
>>> withSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String "B"or explicitly work with S
>>> let x = S $ \f -> f TagInt >>> x mkSome TagInt
>>> case x of S f -> f $ \x' -> case x' of { TagInt -> "I"; TagBool -> "B" } :: String "I"The implementation of mapSome is safe.
>>> let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool >>> mapSome f y mkSome TagBoolbut you can also use:
>>> withSome y (mkSome . f) mkSome TagBool
>>> read "Some TagBool" :: Some Tag mkSome TagBool
>>> read "mkSome TagInt" :: Some Tag mkSome TagInt
>>> data Tag :: Type -> Type where TagInt :: Tag Int; TagBool :: Tag Bool >>> instance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool" >>> classify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> [] >>> instance GRead Tag where greadsPrec _ s = [ (r, rest) | (con, rest) <- lex s, r <- classify con ]You can either use constructor:
>>> let x = Some TagInt >>> x Some TagInt
>>> case x of { Some TagInt -> "I"; Some TagBool -> "B" } :: String "I"or you can use functions
>>> let y = mkSome TagBool >>> y Some TagBool
>>> withSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String "B"The implementation of mapSome is safe.
>>> let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool >>> mapSome f y Some TagBoolbut you can also use:
>>> withSome y (mkSome . f) Some TagBool
>>> read "Some TagBool" :: Some Tag Some TagBool
>>> read "mkSome TagInt" :: Some Tag Some TagInt