我对如何正确使用回旋镖生成 URL 有点困惑。我有以下内容:
data State =
AK | AL | AR | AZ | CA ... WY
data Sitemap
= Home
| State State
| Place State String
deriving (Eq, Ord, Read, Show, Data, Typeable)
$(derivePrinterParsers ''Sitemap)
sitemap ∷ Router Sitemap
sitemap =
( rHome
<> rState . state
<> rPlace . (state </> anyString)
)
state :: PrinterParser StringsError [String] o (State :- o)
state = xmaph read (Just . show) anyString
这似乎可行,但是当我将我的实现state
与文档中的实现进行比较时articleId
,它们似乎以相反的方式工作:
articleId :: Router ArticleId
articleId = xmaph ArticleId (Just . unArticleId) int
这些类型完全不同,看起来它们正朝着相反的方向发展,但我的sitemap
作品和应用程序正确处理了 URL。我认为它应该看起来更像这样:
maybeState :: String → Maybe State
maybeState stateString = case reads stateString of
[(state, "")] -> Just state
_ -> Nothing
stateR :: Router State
stateR = xpure show maybeState
这不会进行类型检查,但即使在上面替换undefined
它的定义也可以,但不会。sitemap
rState . stateR
rPlace . (stateR </> anyString)
似乎这种情况经常出现,可能有一个库函数可以为我处理这个问题,但我没有看到。
编辑:这是我得到的一些类型错误:
对于state = xpure show maybeState
:
Main.hs:56:16:
Couldn't match expected type `State :- ()'
with actual type `[Char]'
Expected type: () -> State :- ()
Actual type: () -> String
In the first argument of `xpure', namely `show'
In the expression: xpure show maybeState
对于state = undefined :: Router State
(此错误在sitemap
定义中):
Main.hs:45:18:
Couldn't match expected type `String :- ()' with actual type `()'
Expected type: PrinterParser
StringsError [String] () (State :- (String :- ()))
Actual type: Router State
In the first argument of `(</>)', namely `state'
In the second argument of `(.)', namely `(state </> anyString)'