Fixing hoogle access by urlencoding parameters

This commit is contained in:
Andrew Gibiansky 2015-03-03 19:21:18 -08:00
parent 6b6a9b8936
commit 05dd79dcdf
3 changed files with 146 additions and 5 deletions

View File

@ -2670,6 +2670,11 @@
"collapsed": false
},
"outputs": [
{
"data": {},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
@ -2769,10 +2774,119 @@
".suggestion-name {\n",
" font-weight: bold;\n",
"}\n",
"</style><span class='err-msg'>InvalidUrlException \"https://www.haskell.org/hoogle/?hoogle=:: [a] -> [(a, b)]&mode=json\" \"Invalid URL\"</span>"
],
"text/plain": [
"InvalidUrlException \"https://www.haskell.org/hoogle/?hoogle=:: [a] -> [(a, b)]&mode=json\" \"Invalid URL\""
"</style><span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:zip'>zip</a> &#x2237; [a] &#x2192; [b] &#x2192; [(a, b)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>base</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Prelude</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>zip takes two lists and returns a list of corresponding pairs. If one input list is short, excess elements of the longer list are discarded. \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Builder-Prim.html#v:-62--42--60-'>(>*<)</a> &#x2237; Monoidal f &#x21D2; f a &#x2192; f b &#x2192; f (a, b)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>bytestring</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.ByteString.Builder.Prim</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>A pairing/concatenation operator for builder primitives, both bounded and fixed size.\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>For example,\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-code'>> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>We can combine multiple primitives using >*< multiple times.\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-code'>> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-Writer-Class.html#v:listens'>listens</a> &#x2237; MonadWriter w m &#x21D2; (w &#x2192; b) &#x2192; m a &#x2192; m (a, b)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>mtl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Control.Monad.Writer.Class</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>listens f m is an action that executes the action m and adds the result of applying f to the output to the value of the computation.\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>* f m = liftM (id *** f) (listen\n",
"</div>\n",
"<div class='hoogle-code'>> \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-Writer-Class.html#v:listen'>listen</a> &#x2237; MonadWriter w m &#x21D2; m a &#x2192; m (a, w)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>mtl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Control.Monad.Writer.Class</span>)</span><div class='hoogle-doc'></div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Graph.html#v:lpre'>lpre</a> &#x2237; Graph gr &#x21D2; gr a b &#x2192; Node &#x2192; [(Node, b)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>fgl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Graph.Inductive.Graph</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>Find all Nodes that link to the given Node and the label of each link. \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Graph.html#v:lsuc'>lsuc</a> &#x2237; Graph gr &#x21D2; gr a b &#x2192; Node &#x2192; [(Node, b)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>fgl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Graph.Inductive.Graph</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>Find all Nodes that are linked from the given Node and the label of each link. \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Query-Monad.html#v:apply'>apply</a> &#x2237; GT m g a &#x2192; m g &#x2192; m (a, g)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>fgl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Graph.Inductive.Query.Monad</span>)</span><div class='hoogle-doc'></div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/QuickCheck/latest/doc/html/Test-QuickCheck-Modifiers.html#v:shrinkState'>shrinkState</a> &#x2237; ShrinkState s a &#x21D2; a &#x2192; s &#x2192; [(a, s)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>QuickCheck</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Test.QuickCheck.Modifiers</span>)</span><div class='hoogle-doc'></div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html#v:execRWS'>execRWS</a> &#x2237; RWS r w s a &#x2192; r &#x2192; s &#x2192; (s, w)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>transformers</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Control.Monad.Trans.RWS.Lazy</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Example.html#v:genUNodes'>genUNodes</a> &#x2237; Int &#x2192; [UNode]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>fgl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Graph.Inductive.Example</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>generate list of unlabeled nodes \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Example.html#v:genLNodes'>genLNodes</a> &#x2237; Enum a &#x21D2; a &#x2192; Int &#x2192; [LNode a]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>fgl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Graph.Inductive.Example</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>generate list of labeled nodes \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/containers/latest/doc/html/Data-Map-Lazy.html#v:elemAt'>elemAt</a> &#x2237; Int &#x2192; Map k a &#x2192; (k, a)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>containers</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Map.Lazy</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>O(log n). Retrieve an element by its index, i.e. by its zero-based index in the sequence sorted by keys. If the index is out of range (less than zero, greater or equal to size of the map), error is called.\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-code'>> elemAt 0 (fromList [(5,\"a\"), (3,\"b\")]) == (3,\"b\")\n",
"> elemAt 1 (fromList [(5,\"a\"), (3,\"b\")]) == (5, \"a\")\n",
"> elemAt 2 (fromList [(5,\"a\"), (3,\"b\")]) Error: index out of range \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOnAll'>breakOnAll</a> &#x2237; Text &#x2192; Text &#x2192; [(Text, Text)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>text</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Text</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>* The entire string prior to the kth match (i.e. the prefix)\n",
"</div>\n",
"<div class='hoogle-text'>* The kth match, followed by the remainder of the string\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>Examples:\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-code'>> breakOnAll \"::\" \"\"\n",
"> ==> []\n",
"> breakOnAll \"/\" \"a/b/c/\"\n",
"> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>The needle parameter may not be empty. \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text-Lazy.html#v:breakOnAll'>breakOnAll</a> &#x2237; Text &#x2192; Text &#x2192; [(Text, Text)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>text</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Text.Lazy</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>* The entire string prior to the kth match (i.e. the prefix)\n",
"</div>\n",
"<div class='hoogle-text'>* The kth match, followed by the remainder of the string\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>Examples:\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-code'>> breakOnAll \"::\" \"\"\n",
"> ==> []\n",
"> breakOnAll \"/\" \"a/b/c/\"\n",
"> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>This function is strict in its first argument, and lazy in its second.\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n",
"</div>\n",
"<div class='hoogle-text'></div>\n",
"<div class='hoogle-text'>The needle parameter may not be empty. \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html#v:execRWST'>execRWST</a> &#x2237; Monad m &#x21D2; RWST r w s m a &#x2192; r &#x2192; s &#x2192; m (s, w)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>transformers</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Control.Monad.Trans.RWS.Lazy</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Query-BFS.html#v:level'>level</a> &#x2237; Graph gr &#x21D2; Node &#x2192; gr a b &#x2192; [(Node, Int)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>fgl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Graph.Inductive.Query.BFS</span>)</span><div class='hoogle-doc'></div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Query-Dominators.html#v:iDom'>iDom</a> &#x2237; Graph gr &#x21D2; gr a b &#x2192; Node &#x2192; [(Node, Node)]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>fgl</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Graph.Inductive.Query.Dominators</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>return immediate dominators for each node of a graph, given a root \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/syb/latest/doc/html/Data-Generics-Twins.html#v:gmapAccumT'>gmapAccumT</a> &#x2237; Data d &#x21D2; (&#x2200; e. Data e &#x21D2; a &#x2192; e &#x2192; (a, e)) &#x2192; a &#x2192; d &#x2192; (a, d)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>syb</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Data.Generics.Twins</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>gmapT with accumulation \n",
"</div>\n",
"</div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/HTTP/latest/doc/html/Network-BufferType.html#v:buf-95-span'>buf_span</a> &#x2237; BufferOp a &#x2192; (Char &#x2192; Bool) &#x2192; a &#x2192; (a, a)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>HTTP</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Network.BufferType</span>)</span><div class='hoogle-doc'></div>\n",
"<span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/HTTP/latest/doc/html/Network-BufferType.html#v:buf-95-splitAt'>buf_splitAt</a> &#x2237; BufferOp a &#x2192; Int &#x2192; a &#x2192; (a, a)</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>HTTP</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Network.BufferType</span>)</span><div class='hoogle-doc'></div>\n"
]
},
"metadata": {},

View File

@ -1212,6 +1212,7 @@ formatErrorWithClass cls =
replace "\n" "<br/>" .
replace useDashV "" .
replace "Ghci" "IHaskell" .
replace "interactive:" "" .
fixDollarSigns .
rstrip .
typeCleaner

View File

@ -14,7 +14,9 @@ import Network.HTTP.Client.TLS
import Data.Aeson
import Data.String.Utils
import Data.List (elemIndex, (!!), last)
import Data.Char (isAscii, isAlphaNum)
import qualified Data.ByteString.Lazy.Char8 as Char
import qualified Prelude as P
import IHaskell.IPython
@ -58,7 +60,7 @@ instance FromJSON HoogleResponse where
-- message or the successful JSON result.
query :: String -> IO (Either String String)
query str = do
request <- parseUrl $ queryUrl str
request <- parseUrl $ queryUrl $ urlEncode str
response <- try $ withManager tlsManagerSettings $ httpLbs request
return $ case response of
Left err -> Left $ show (err :: SomeException)
@ -67,6 +69,30 @@ query str = do
queryUrl :: String -> String
queryUrl = printf "https://www.haskell.org/hoogle/?hoogle=%s&mode=json"
-- | Copied from the HTTP package.
urlEncode :: String -> String
urlEncode [] = []
urlEncode (ch:t)
| (isAscii ch && isAlphaNum ch) || ch `P.elem` "-_.~" = ch : urlEncode t
| not (isAscii ch) = P.foldr escape (urlEncode t) (eightBs [] (P.fromEnum ch))
| otherwise = escape (P.fromEnum ch) (urlEncode t)
where
escape :: Int -> String -> String
escape b rs = '%':showH (b `P.div` 16) (showH (b `mod` 16) rs)
showH :: Int -> String -> String
showH x xs
| x <= 9 = toEnum (o_0 + x) : xs
| otherwise = toEnum (o_A + (x-10)) : xs
where
o_0 = P.fromEnum '0'
o_A = P.fromEnum 'A'
eightBs :: [Int] -> Int -> [Int]
eightBs acc x
| x <= 0xff = (x:acc)
| otherwise = eightBs ((x `mod` 256) : acc) (x `P.div` 256)
-- | Search for a query on Hoogle.
-- Return all search results.
search :: String -> IO [HoogleResult]