17
考慮以下類型簽名:免費替代仿函數生成optparse,應用性分析器
data Foo x = Foo {
name :: String
, reader :: String -> x
}
instance Functor Foo where
fmap f (Foo n r) = Foo n $ f . r
現在我展示從自然轉化Foo
到optparse-applicative
的Parser
類型:
import qualified Options.Applicative as CL
mkParser :: Foo a -> CL.Parser a
mkParser (Foo n _) = CL.option CL.disabled (CL.long n)
(好吧,這有點無用,但它將用於討論)。
現在我把Bar
將超過Foo
免費的替代函子:
type Bar a = Alt Foo a
鑑於這是一個免費的函子,我應該能夠解除mkParser
成從Bar
自然改造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
事實上,這有效,並給我一個Parser
回來。然而,這是一個非常無用的工具,因爲試圖做很多事情會導致無限循環。例如,如果我試圖描述它:
CL.cmdDesc clFoo
> Chunk {unChunk =
並掛起,直到中斷。
原因似乎是optparse-applicative
cheats在其定義many
和some
:它使用monadic解析下的封面。
我在這裏做錯了什麼?我看不出如何,因爲這樣,就有可能以這種方式構建解析器。有任何想法嗎?
你可以擴展應用性自由包含了'many'和'some'構造以及再解釋它們有點不同,也許。 – 2014-11-03 21:48:14