2015-05-20 23 views
6

在Haskell包Network.URI中有parseURI :: String -> Maybe URI函數。如何用Network.URI代碼表示一個靜態Haskell URI?

我想在我的代碼中有幾個靜態URI。寫下面的內容是否合理?

Just myURI = parseURI "http://google.com/" 

「問題」這個是,如果URI字符串實際上是畸形的,它是隻抓到在運行時用的模式失敗的例外。

我想避免直接構造URI數據類型的枯燥乏味(這會破壞URI並使其在某種程度上失去其概念意義)。

有沒有更好的方法在代碼中擁有靜態URI並且更「安全」?

回答

0

Is it reasonable to write the following?

不,不要用Just模式匹配,除非你確信你的URI是不是畸形。像這樣的URI將給Nothing導致運行時錯誤:

λ> parseURI "http:/\\/google.com/" 
Nothing 

相反,只是表示Maybe類型URI和做對即用的功能,如fmap和他人的計算。一個另一種方法是檢查它是否包含一個有效的URI使用功能isURI或任何在Network.URI規定的其他適當的功能,然後處理適當的情況:

λ> isURI "http:/\\/google.com/" 
False 
λ> isURI "http://google.com" 
True 
0

我建議直接使用URIURIAuth構造。你得到更多的文字,但你也得到一個靜態的保證,你確實有一個URI。但是,這是要避免:)

I'd like to avoid the tedium of constructing the URI datatype directly (which breaks apart the URI and makes it lose its conceptual meaning somewhat).

如果你真的使用字符串文字設置,那麼你可以打開OverloadedStrings和定義IsString實例Maybe URI像這樣的內容:

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE OverloadedStrings #-} 

import Data.String 
import Network.URI 

instance IsString (Maybe URI) where 
    isString = parseURI 

someUri :: Maybe URI 
someUri = "http://google.ca" 

您無法安全地轉儲Maybe;你只需要使用它。

6

如何使用Template Haskell在編譯時使用isURI驗證靜態URL?現在在運行時使用fromJust是安全的,因爲URL必須是有效的。

例如,像這樣定義staticURI

{-# LANGUAGE TemplateHaskell #-} 

module URI where 

import Data.Maybe (fromJust) 
import Network.URI (URI, isURI, parseURI) 
import Language.Haskell.TH (Q, TExp) 

staticURI :: String -> Q (TExp URI) 
staticURI uri | isURI uri = [|| fromJust $ parseURI uri ||] 
       | otherwise = fail $ "Invalid URI: " ++ uri 

然後,你可以在這樣的其他模塊中定義你的URL。

{-# LANGUAGE TemplateHaskell #-} 

import Network.URI (URI) 
import URI (staticURI) 

url :: URI 
url = $$(staticURI "http://www.google.com/") 

badUrl :: URI 
badUrl = $$(staticURI "http://www.google.com/##") 

當你傳遞了錯誤的URL來staticURI,編譯器會發出錯誤。

Invalid URI: http://www.google.com/## 
In the Template Haskell splice 
    $$(staticURI "http://www.google.com/##") 
In the expression: $$(staticURI "http://www.google.com/##") 
In an equation for ‘url’: 
    url = $$(staticURI "http://www.google.com/##")