diff --git a/notebooks/IHaskell.ipynb b/notebooks/IHaskell.ipynb index d1a040ba..b1972d9f 100644 --- a/notebooks/IHaskell.ipynb +++ b/notebooks/IHaskell.ipynb @@ -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", - "InvalidUrlException \"https://www.haskell.org/hoogle/?hoogle=:: [a] -> [(a, b)]&mode=json\" \"Invalid URL\"" - ], - "text/plain": [ - "InvalidUrlException \"https://www.haskell.org/hoogle/?hoogle=:: [a] -> [(a, b)]&mode=json\" \"Invalid URL\"" + "zip ∷ [a] → [b] → [(a, b)](package base, module Prelude)
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", + "
\n", + "
\n", + "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)(package bytestring, module Data.ByteString.Builder.Prim)
A pairing/concatenation operator for builder primitives, both bounded and fixed size.\n", + "
\n", + "
\n", + "
For example,\n", + "
\n", + "
\n", + "
> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", + "
\n", + "
\n", + "
We can combine multiple primitives using >*< multiple times.\n", + "
\n", + "
\n", + "
> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", + "
\n", + "
\n", + "listens ∷ MonadWriter w m ⇒ (w → b) → m a → m (a, b)(package mtl, module Control.Monad.Writer.Class)
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", + "
\n", + "
\n", + "
* f m = liftM (id *** f) (listen\n", + "
\n", + "
> \n", + "
\n", + "
\n", + "listen ∷ MonadWriter w m ⇒ m a → m (a, w)(package mtl, module Control.Monad.Writer.Class)
\n", + "lpre ∷ Graph gr ⇒ gr a b → Node → [(Node, b)](package fgl, module Data.Graph.Inductive.Graph)
Find all Nodes that link to the given Node and the label of each link. \n", + "
\n", + "
\n", + "lsuc ∷ Graph gr ⇒ gr a b → Node → [(Node, b)](package fgl, module Data.Graph.Inductive.Graph)
Find all Nodes that are linked from the given Node and the label of each link. \n", + "
\n", + "
\n", + "apply ∷ GT m g a → m g → m (a, g)(package fgl, module Data.Graph.Inductive.Query.Monad)
\n", + "shrinkState ∷ ShrinkState s a ⇒ a → s → [(a, s)](package QuickCheck, module Test.QuickCheck.Modifiers)
\n", + "execRWS ∷ RWS r w s a → r → s → (s, w)(package transformers, module Control.Monad.Trans.RWS.Lazy)
Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n", + "
\n", + "
\n", + "genUNodes ∷ Int → [UNode](package fgl, module Data.Graph.Inductive.Example)
generate list of unlabeled nodes \n", + "
\n", + "
\n", + "genLNodes ∷ Enum a ⇒ a → Int → [LNode a](package fgl, module Data.Graph.Inductive.Example)
generate list of labeled nodes \n", + "
\n", + "
\n", + "elemAt ∷ Int → Map k a → (k, a)(package containers, module Data.Map.Lazy)
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", + "
\n", + "
\n", + "
> 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", + "
\n", + "
\n", + "breakOnAll ∷ Text → Text → [(Text, Text)](package text, module Data.Text)
O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "
\n", + "
\n", + "
* The entire string prior to the kth match (i.e. the prefix)\n", + "
\n", + "
* The kth match, followed by the remainder of the string\n", + "
\n", + "
\n", + "
Examples:\n", + "
\n", + "
\n", + "
> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n", + "
\n", + "
The needle parameter may not be empty. \n", + "
\n", + "
\n", + "breakOnAll ∷ Text → Text → [(Text, Text)](package text, module Data.Text.Lazy)
O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "
\n", + "
\n", + "
* The entire string prior to the kth match (i.e. the prefix)\n", + "
\n", + "
* The kth match, followed by the remainder of the string\n", + "
\n", + "
\n", + "
Examples:\n", + "
\n", + "
\n", + "
> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "
\n", + "
\n", + "
This function is strict in its first argument, and lazy in its second.\n", + "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n", + "
\n", + "
The needle parameter may not be empty. \n", + "
\n", + "
\n", + "execRWST ∷ Monad m ⇒ RWST r w s m a → r → s → m (s, w)(package transformers, module Control.Monad.Trans.RWS.Lazy)
Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n", + "
\n", + "
\n", + "level ∷ Graph gr ⇒ Node → gr a b → [(Node, Int)](package fgl, module Data.Graph.Inductive.Query.BFS)
\n", + "iDom ∷ Graph gr ⇒ gr a b → Node → [(Node, Node)](package fgl, module Data.Graph.Inductive.Query.Dominators)
return immediate dominators for each node of a graph, given a root \n", + "
\n", + "
\n", + "gmapAccumT ∷ Data d ⇒ (∀ e. Data e ⇒ a → e → (a, e)) → a → d → (a, d)(package syb, module Data.Generics.Twins)
gmapT with accumulation \n", + "
\n", + "
\n", + "buf_span ∷ BufferOp a → (Char → Bool) → a → (a, a)(package HTTP, module Network.BufferType)
\n", + "buf_splitAt ∷ BufferOp a → Int → a → (a, a)(package HTTP, module Network.BufferType)
\n" ] }, "metadata": {}, diff --git a/src/IHaskell/Eval/Evaluate.hs b/src/IHaskell/Eval/Evaluate.hs index a40ee1ce..b3c44319 100644 --- a/src/IHaskell/Eval/Evaluate.hs +++ b/src/IHaskell/Eval/Evaluate.hs @@ -1212,6 +1212,7 @@ formatErrorWithClass cls = replace "\n" "
" . replace useDashV "" . replace "Ghci" "IHaskell" . + replace "‘interactive:" "‘" . fixDollarSigns . rstrip . typeCleaner diff --git a/src/IHaskell/Eval/Hoogle.hs b/src/IHaskell/Eval/Hoogle.hs index f6b2c690..bea06598 100644 --- a/src/IHaskell/Eval/Hoogle.hs +++ b/src/IHaskell/Eval/Hoogle.hs @@ -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]