Consider the following type signatures:
data Foo x = Foo {
name :: String
, reader :: String -> x
}
instance Functor Foo where
fmap f (Foo n r) = Foo n $ f . r
Now I show a natural transformation from Foo
to optparse-applicative
's Parser
type:
import qualified Options.Applicative as CL
mkParser :: Foo a -> CL.Parser a
mkParser (Foo n _) = CL.option CL.disabled ( CL.long n )
(Okay, it's a bit useless, but it'll serve for discussion).
Now I take Bar
to be the free alternative functor over Foo
:
type Bar a = Alt Foo a
Given this is a free functor, I should be able to lift mkParser
into a natural transformation from Bar
to Parser
:
foo :: String -> (String -> x) -> Bar x
foo n r = liftAlt $ Foo n r
myFoo :: Bar [String]
myFoo = many $ foo "Hello" (\_ -> "Hello")
clFoo :: CL.Parser [String]
clFoo = runAlt mkParser $ myFoo
And indeed, this works and gives me a Parser
back. However, it's a pretty useless one, because trying to do much with it results in an infinite loop. For example, if I try to describe it:
CL.cmdDesc clFoo
> Chunk {unChunk =
And hangs until interrupted.
The reason for this seems to be that optparse-applicative
cheats in its definitions of many
and some
: it uses monadic parsing under the covers.
Am I doing something wrong here? I don't see how, given this, it's possible to construct a parser in this way. Any ideas?