In the Haskell package Network.URI
there is the parseURI :: String -> Maybe URI
function.
I'd like to have a couple of static URIs in my code. Is it reasonable to write the following?
Just myURI = parseURI "http://google.com/"
The "problem" with this is that if the URI string is actually malformed, it is only caught at runtime with a pattern failed exception.
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).
Is there a better way to have the static URI in code and be more "safe"?
How about using Template Haskell to validate a static URL using isURI
at compile time? It's safe to use fromJust
at runtime now that the URL must be valid.
For example, define staticURI
like this.
{-# 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
Then, you can define your URL in other modules like this.
{-# 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/##")
When you pass a malformed URL to staticURI
, a compiler will emit an error.
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/##")
Is it reasonable to write the following?
No, don't pattern match with Just
unless you are sure that your URI isn't malformed. A URI like this will give Nothing
leading to runtime error:
λ> parseURI "http:/\\/google.com/"
Nothing
Instead, just represent the URI in Maybe
type and do your computations on that using functions like fmap
and others. One another way would be to check if it contains a valid URI using the function isURI
or any of the other appropriate functions defined in Network.URI and then handle the appropriate cases:
λ> isURI "http:/\\/google.com/"
False
λ> isURI "http://google.com"
True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With