2015-10-26 26 views
3

有沒有一種方法可以更簡潔地編寫它?我有很多看起來像這樣的功能。他們每個人都有一些布爾條件,然後要麼返回值或Nothing像「when」這樣的函數返回一個值嗎?

rootMiddleware :: Application -> Application 
rootMiddleware app req respond = 
    fromMaybe next . fmap respond $ 
      serveIndex ["questionnaire"] "../app/answer/answer.html" req 
     <|> serveIndex ["survey"] "../app/builder/builder.html" req 
     <|> redirect [] "/survey/forms" req 

    where 
    next = app req respond 

serveIndex :: [Text] -> FilePath -> Request -> Maybe Response 
serveIndex prefix fp req = 
    if prefix `isPrefixOf` pathInfo req 
     then Just $ responseFile status200 [("Content-Type", "text/html")] fp Nothing 
     else Nothing 

redirect :: [Text] -> ByteString -> Request -> Maybe Response 
redirect pathParts url req = 
    if pathParts == pathInfo req 
     then Just $ redirectTo url 
     else Nothing 

when是非常接近,但它不會讓你在合用的返回值。這種情況有沒有相同的東西?

+0

似乎很簡練我已經,你可以使用'布爾:: BOOL - > A - > A - >了'代替如果你發現更具吸引力的話,那麼「if .. then .. else」 – cdk

回答

9

這聽起來像你正在尋找guard

guard :: Alternative f => Bool -> f() 
guard c = if c then pure() else empty 

然後你可以重寫

if c then Just x else Nothing 

x <$ guard c 

當你不直去Just,考慮

guard c *> e 

它與do表示法很好地工作。感謝Daniel Wagner提供的<$表達式。

還要注意

fromMaybe x . fmap f 

更好書面

maybe x f 
+3

['guard'](https://downloads.haskell.org/~ghc/latest/docs/html/libraries/base-4.8.1.0/Control -Monad.html#v:guard)不使用臭名昭着的'失敗'。它曾經使用'mzero',但是由於AMP已經推廣使用'Alternative'的'empty'。 –

+0

@ØrjanJohansen,哎呀!聽到那個消息很開心。 – dfeuer

+1

我更喜歡定義'():: Alternative f => Bool - > f a - > f a; True x = x; False x = empty',所以我們可以寫'c pure x',而不是'x <$ guard c'',這對我來說更加自我描述。 'mfilter'也可以使用。 – user3237465

相關問題