2015-05-20 10 views
6

Nella confezione Haskell Network.URI c'è la funzione parseURI :: String -> Maybe URI.Come indicare un URI Haskell statico nel codice con Network.URI?

Mi piacerebbe avere un paio di URI statici nel mio codice. È ragionevole scrivere quanto segue?

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

Il "problema" di questo è che se la stringa URI è in realtà malformati, si raggiunge solo in fase di esecuzione con un modello fallito eccezione.

Mi piacerebbe evitare la noia di costruire direttamente il tipo di dati URI (che separa l'URI e fa in qualche modo perdere il suo significato concettuale).

C'è un modo migliore per avere l'URI statico nel codice ed essere più "sicuri"?

risposta

0

Is it reasonable to write the following?

No, non corrispondono modello con Just se non si è sicuri che il vostro URI non è valido. Un URI come questo darà Nothing che porta a Errore di runtime:

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

Invece, basta rappresentano l'URI in Maybe tipo e fare la tua calcoli su quel che utilizzano funzioni come fmap e altri. Un altro modo sarebbe quello di controllare se contiene un URI valido utilizzando la funzione isURI o una qualsiasi delle altre funzioni appropriate definite nella Network.URI e quindi gestire i casi appropriati:

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

mi consiglia di utilizzare direttamente i costruttori URI e URIAuth . Ottieni un po 'più di testo, ma ottieni anche una garanzia statica che hai davvero un URI. Ma questo è ciò che si vuole evitare :)

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).

Se sei veramente impostato sull'utilizzo di stringhe, allora si potrebbe accendere OverloadedStrings e definire un'istanza IsString per Maybe URI in questo modo:

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

import Data.String 
import Network.URI 

instance IsString (Maybe URI) where 
    isString = parseURI 

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

Non è possibile scaricare in modo sicuro lo Maybe; dovrai solo lavorarci sopra.

6

Come utilizzare Template Haskell per convalidare un URL statico utilizzando isURI in fase di compilazione? È sicuro utilizzare fromJust in fase di esecuzione ora che l'URL deve essere valido.

Ad esempio, definire staticURI come questo.

{-# 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 

Quindi, è possibile definire l'URL in altri moduli come questo.

{-# 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/##") 

Quando si passa un URL non valido per staticURI, un compilatore emetterà un errore.

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/##")