From f95b71d2933ce24e366136603a4037b04faf92d2 Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Wed, 24 Oct 2018 20:30:59 +0200 Subject: [PATCH 01/10] Use hoogle v5. Hoogle v5 uses a different json representation for the data, requires a new URL and also contains HTML markup inside the json fields. This commit removes all markup to be able to handle the hoogle responses using the same structure as with the previous response structure (from hoogle v4). --- ihaskell.cabal | 2 + src/IHaskell/Eval/Hoogle.hs | 87 +++++++++++++++++++------------ src/tests/Hspec.hs | 4 +- src/tests/IHaskell/Test/Hoogle.hs | 63 ++++++++++++++++++++++ 4 files changed, 123 insertions(+), 33 deletions(-) create mode 100644 src/tests/IHaskell/Test/Hoogle.hs diff --git a/ihaskell.cabal b/ihaskell.cabal index a033bdd3..751bd83b 100644 --- a/ihaskell.cabal +++ b/ihaskell.cabal @@ -164,6 +164,7 @@ Test-Suite hspec IHaskell.Test.Completion IHaskell.Test.Util IHaskell.Test.Parser + IHaskell.Test.Hoogle default-language: Haskell2010 build-depends: base, @@ -178,6 +179,7 @@ Test-Suite hspec directory, text, shelly, + raw-strings-qq, setenv source-repository head diff --git a/src/IHaskell/Eval/Hoogle.hs b/src/IHaskell/Eval/Hoogle.hs index bb326999..aa0521cc 100644 --- a/src/IHaskell/Eval/Hoogle.hs +++ b/src/IHaskell/Eval/Hoogle.hs @@ -1,24 +1,33 @@ -{-# LANGUAGE NoImplicitPrelude, FlexibleInstances, OverloadedStrings #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE OverloadedStrings #-} module IHaskell.Eval.Hoogle ( search, document, render, OutputFormat(..), - HoogleResult, + HoogleResult(..), + HoogleResponse(..), + parseResponse, ) where +import qualified Data.ByteString.Char8 as CBS +import qualified Data.ByteString.Lazy as LBS +import Data.Either (either) import IHaskellPrelude -import qualified Data.ByteString.Lazy as LBS -import qualified Data.ByteString.Char8 as CBS +import Data.Aeson +import Data.Char (isAlphaNum, isAscii) +import qualified Data.List as List +import qualified Data.Text as T +import Data.Vector (toList) import Network.HTTP.Client import Network.HTTP.Client.TLS -import Data.Aeson -import qualified Data.List as List -import Data.Char (isAscii, isAlphaNum) -import StringUtils (split, strip, replace) +import StringUtils (replace, split, strip) + +import Debug.Trace -- | Types of formats to render output to. data OutputFormat = Plain -- ^ Render to plain text. @@ -35,17 +44,19 @@ data HoogleResult = SearchResult HoogleResponse data HoogleResponseList = HoogleResponseList [HoogleResponse] instance FromJSON HoogleResponseList where - parseJSON (Object obj) = do - results <- obj .: "results" - HoogleResponseList <$> mapM parseJSON results + parseJSON (Array arr) = + HoogleResponseList <$> mapM parseJSON (toList arr) - parseJSON _ = fail "Expected object with 'results' field." + parseJSON _ = fail "Expected array." instance FromJSON HoogleResponse where parseJSON (Object obj) = - HoogleResponse <$> obj .: "location" <*> obj .: "self" <*> obj .: "docs" + HoogleResponse + <$> obj .: "url" + <*> (removeMarkup <$> obj .: "item") + <*> obj .: "docs" - parseJSON _ = fail "Expected object with fields: location, self, docs" + parseJSON _ = fail "Expected object with fields: url, item, docs" -- | Query Hoogle for the given string. This searches Hoogle using the internet. It returns either -- an error message or the successful JSON result. @@ -59,7 +70,7 @@ query str = do where queryUrl :: String -> String - queryUrl = printf "https://www.haskell.org/hoogle/?hoogle=%s&mode=json" + queryUrl = printf "http://hoogle.haskell.org/?hoogle=%s&mode=json" -- | Copied from the HTTP package. urlEncode :: String -> String @@ -87,18 +98,16 @@ urlEncode (ch:t) -- | Search for a query on Hoogle. Return all search results. search :: String -> IO [HoogleResult] -search string = do - response <- query string - return $ - case response of - Left err -> [NoResult err] - Right jsn -> - case eitherDecode $ LBS.fromStrict $ CBS.pack jsn of - Left err -> [NoResult err] - Right results -> - case map SearchResult $ (\(HoogleResponseList l) -> l) results of - [] -> [NoResult "no matching identifiers found."] - res -> res +search string = either ((:[]) . NoResult) parseResponse <$> query string + +parseResponse :: String -> [HoogleResult] +parseResponse jsn = + case eitherDecode $ LBS.fromStrict $ CBS.pack jsn of + Left err -> [NoResult err] + Right results -> + case map SearchResult $ (\(HoogleResponseList l) -> l) results of + [] -> [NoResult "no matching identifiers found."] + res -> res -- | Look up an identifier on Hoogle. Return documentation for that identifier. If there are many -- identifiers, include documentation for all of them. @@ -118,13 +127,13 @@ document string = do matches _ = False toDocResult (SearchResult resp) = Just $ DocResult resp - toDocResult (DocResult _) = Nothing - toDocResult (NoResult _) = Nothing + toDocResult (DocResult _) = Nothing + toDocResult (NoResult _) = Nothing -- | Render a Hoogle search result into an output format. render :: OutputFormat -> HoogleResult -> String render Plain = renderPlain -render HTML = renderHtml +render HTML = renderHtml -- | Render a Hoogle result to plain text. renderPlain :: HoogleResult -> String @@ -182,7 +191,7 @@ renderSelf string loc packageSub package | otherwise = - let [name, args] = split "::" string + let [name, args] = trace string $ split "::" string package = extractPackageName loc modname = extractModuleName loc in span "hoogle-name" @@ -231,7 +240,7 @@ renderDocs doc = isPrefixOf ">" (strip s2) isCode xs = case xs of - [] -> False + [] -> False (s:_) -> isPrefixOf ">" $ strip s makeBlock xs = if isCode xs @@ -259,3 +268,17 @@ span = printf "%s" link :: String -> String -> String link = printf "%s" + +-- | very explicit cleaning of the type signature in the hoogle 5 response, +-- to remove html markup and escaped characters. +removeMarkup :: String -> String +removeMarkup s = T.unpack $ List.foldl (flip ($)) (T.pack s) replaceAll + where replacements :: [ (T.Text, T.Text) ] + replacements = [ ( "<0>", "" ) + , ( "", "" ) + , ( ">", ">" ) + , ( "<", "<" ) + , ( "", "") + , ( "", "") + ] + replaceAll = uncurry T.replace <$> replacements diff --git a/src/tests/Hspec.hs b/src/tests/Hspec.hs index 38b58169..eb708f3b 100644 --- a/src/tests/Hspec.hs +++ b/src/tests/Hspec.hs @@ -7,10 +7,12 @@ import Test.Hspec import IHaskell.Test.Completion (testCompletions) import IHaskell.Test.Parser (testParser) import IHaskell.Test.Eval (testEval) +import IHaskell.Test.Hoogle (testHoogle) main :: IO () -main = +main = hspec $ do testParser testEval testCompletions + testHoogle diff --git a/src/tests/IHaskell/Test/Hoogle.hs b/src/tests/IHaskell/Test/Hoogle.hs new file mode 100644 index 00000000..49227b52 --- /dev/null +++ b/src/tests/IHaskell/Test/Hoogle.hs @@ -0,0 +1,63 @@ +{-# LANGUAGE QuasiQuotes #-} + +module IHaskell.Test.Hoogle ( testHoogle ) where + +import Test.Hspec +import Text.RawString.QQ + +import IHaskell.Eval.Hoogle +-- import Data.Text (unpack) +-- import qualified Data.Text.IO as T +preludeFmapJson :: String +preludeFmapJson = [r| +[ + { + "url": "https://hackage.haskell.org/package/base/docs/Prelude.html#v:fmap", + "module": { + "url": "https://hackage.haskell.org/package/base/docs/Prelude.html", + "name": "Prelude" + }, + "package": { + "url": "https://hackage.haskell.org/package/base", + "name": "base" + }, + "item": "<0>fmap :: Functor f => (a -> b) -> f a -> f b", + "type": "", + "docs": "" + } +]|] + +moduleJson :: String +moduleJson = [r| +[ + { + "url": "https://hackage.haskell.org/package/universum/docs/Universum-Functor-Fmap.html", + "module": {}, + "package": { + "url": "https://hackage.haskell.org/package/universum", + "name": "universum" + }, + "item": "module Universum.Functor.<0>Fmap", + "type": "module", + "docs": "This module contains useful functions to work with Functor type\nclass.\n" + } +]|] + +testHoogle :: Spec +testHoogle = describe "Hoogle Search" $ do + describe "fmap search result" $ do + let results = parseResponse preludeFmapJson :: [HoogleResult] + it "should find 1 results" $ do + length results `shouldBe` 1 + let (SearchResult (HoogleResponse loc signature _docUrl)) = head results + it "should not contain html markup" $ do + loc `shouldBe` "https://hackage.haskell.org/package/base/docs/Prelude.html#v:fmap" + signature `shouldBe` "fmap :: Functor f => (a -> b) -> f a -> f b" + describe "module result" $ do + let results = parseResponse moduleJson :: [HoogleResult] + let (SearchResult (HoogleResponse _loc signature _docUrl)) = head results + it "should not contain html markup" $ do + signature `shouldBe` "module Universum.Functor.Fmap" + it "should be renderable" $ do + (render Plain $ head results) `shouldStartWith` "module Universum.Functor.Fmap" + (render HTML $ head results) `shouldStartWith` "module" From 972450cd5a44141245193d774ce22f9b0d920083 Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Tue, 30 Oct 2018 21:33:48 +0100 Subject: [PATCH 02/10] disable debug trace. --- src/IHaskell/Eval/Hoogle.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/IHaskell/Eval/Hoogle.hs b/src/IHaskell/Eval/Hoogle.hs index aa0521cc..23b647f5 100644 --- a/src/IHaskell/Eval/Hoogle.hs +++ b/src/IHaskell/Eval/Hoogle.hs @@ -27,8 +27,6 @@ import Network.HTTP.Client.TLS import StringUtils (replace, split, strip) -import Debug.Trace - -- | Types of formats to render output to. data OutputFormat = Plain -- ^ Render to plain text. | HTML -- ^ Render to HTML. @@ -191,7 +189,7 @@ renderSelf string loc packageSub package | otherwise = - let [name, args] = trace string $ split "::" string + let [name, args] = split "::" string package = extractPackageName loc modname = extractModuleName loc in span "hoogle-name" From c693ce307e2db8d0117ab47c7b21ae1a1c2eb3f9 Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Thu, 1 Nov 2018 10:03:17 +0100 Subject: [PATCH 03/10] markup removal improvements. it's possible to have some content between `` and `<0>` so separating the expressions to handle this case. --- src/IHaskell/Eval/Hoogle.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/IHaskell/Eval/Hoogle.hs b/src/IHaskell/Eval/Hoogle.hs index 23b647f5..b13432f9 100644 --- a/src/IHaskell/Eval/Hoogle.hs +++ b/src/IHaskell/Eval/Hoogle.hs @@ -272,8 +272,10 @@ link = printf "%s" removeMarkup :: String -> String removeMarkup s = T.unpack $ List.foldl (flip ($)) (T.pack s) replaceAll where replacements :: [ (T.Text, T.Text) ] - replacements = [ ( "<0>", "" ) - , ( "", "" ) + replacements = [ ( "", "" ) + , ( "", "" ) + , ( "<0>", "" ) + , ( "", "" ) , ( ">", ">" ) , ( "<", "<" ) , ( "", "") From 6788944a4519bd6a6f45e50dbfb0292a321fc469 Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Thu, 1 Nov 2018 20:45:32 +0100 Subject: [PATCH 04/10] Support `type` as `item`. --- src/IHaskell/Eval/Hoogle.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/IHaskell/Eval/Hoogle.hs b/src/IHaskell/Eval/Hoogle.hs index b13432f9..2a87544c 100644 --- a/src/IHaskell/Eval/Hoogle.hs +++ b/src/IHaskell/Eval/Hoogle.hs @@ -188,6 +188,12 @@ renderSelf string loc span "hoogle-class" (link loc $ extractNewtype string) ++ packageSub package + | "type" `isPrefixOf` string = + let package = extractPackageName loc + in nwt ++ " " ++ + span "hoogle-class" (link loc $ extractType string) ++ + packageSub package + | otherwise = let [name, args] = split "::" string package = extractPackageName loc @@ -204,6 +210,7 @@ renderSelf string loc extractClass = strip . replace "class" "" extractData = strip . replace "data" "" extractNewtype = strip . replace "newtype" "" + extractType = strip . replace "newtype" "" pkg = span "hoogle-head" "package" mdl = span "hoogle-head" "module" cls = span "hoogle-head" "class" From 2f49c3574388f8283944e364d80fefdbe538d939 Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Thu, 1 Nov 2018 20:46:54 +0100 Subject: [PATCH 05/10] no more html-formatting for the hoogle docs. Hoogle v5 `docs` field already contains markup, so we just use the field content directly. --- src/IHaskell/Eval/Hoogle.hs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/IHaskell/Eval/Hoogle.hs b/src/IHaskell/Eval/Hoogle.hs index 2a87544c..b946b324 100644 --- a/src/IHaskell/Eval/Hoogle.hs +++ b/src/IHaskell/Eval/Hoogle.hs @@ -237,21 +237,7 @@ renderSelf string loc ", " ++ mdl ++ " " ++ span "hoogle-module" modname ++ ")" renderDocs :: String -> String -renderDocs doc = - let groups = List.groupBy bothAreCode $ lines doc - nonull = filter (not . null . strip) - bothAreCode s1 s2 = - isPrefixOf ">" (strip s1) && - isPrefixOf ">" (strip s2) - isCode xs = - case xs of - [] -> False - (s:_) -> isPrefixOf ">" $ strip s - makeBlock xs = - if isCode xs - then div' "hoogle-code" $ unlines $ nonull xs - else div' "hoogle-text" $ unlines $ nonull xs - in div' "hoogle-doc" $ unlines $ map makeBlock groups +renderDocs doc = div' "hoogle-doc" doc extractPackageName :: String -> Maybe String extractPackageName lnk = do From 31a59439ac059e8852f712c2176b22115d93457e Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Thu, 1 Nov 2018 21:23:52 +0100 Subject: [PATCH 06/10] Update notebook: hoogle response changed. --- notebooks/IHaskell.ipynb | 2229 ++++++++++++++++++++++++++++---------- 1 file changed, 1632 insertions(+), 597 deletions(-) diff --git a/notebooks/IHaskell.ipynb b/notebooks/IHaskell.ipynb index 2818d75f..7ef7edfe 100644 --- a/notebooks/IHaskell.ipynb +++ b/notebooks/IHaskell.ipynb @@ -2,10 +2,7 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "![](https://camo.githubusercontent.com/f6540337202bb3b0c2545d90de0791c9196f9510/68747470733a2f2f7261772e6769746875622e636f6d2f67696269616e736b792f494861736b656c6c2f6d61737465722f68746d6c2f6c6f676f2d36347836342e706e67)\n", "\n", @@ -21,11 +18,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -54,10 +47,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "As you can see, each input cell get an execution number. The first input cell is labeled `In [1]`. Just like in GHCi, the output of the last executed statement or expression is available via the `it` variable - however, in addition, the output of the $n$th cell is available via the `itN` variable. For example, if we wanted to see what the first cell printed, we can go ahead and output that:" ] @@ -65,11 +55,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -87,10 +73,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to simple code cells such as the ones you see, you can also have other types of cells. All of this inline text, for instance, is written using Markdown cells, which support the majority of Github markdown syntax. This lets you embed images and formatting and arbitrary HTML interspersed with your Haskell code. In addition, you can export these notebooks into HTML or even as presentations using `reveal.js`. \n", "\n", @@ -100,11 +83,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -127,10 +106,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to multi-line expressions, IHaskell supports most things that you could put in a standard Haskell file. For example, we can have function bindings without the `let` that GHCi requires. (As long as you group type signatures and their corresponding declarations together, you can use pattern matching and put signatures on your top-level declarations!)" ] @@ -138,11 +114,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -174,10 +146,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "So far we've just looked at pure functions, but nothing is stopping us from doing IO." ] @@ -185,11 +154,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -207,10 +172,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "IHaskell supports most GHC extensions via the `:extension` directive (or any shorthand thereof)." ] @@ -218,11 +180,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -329,11 +287,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- And enable extensions.\n", @@ -343,10 +297,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Data declarations do pretty much what you expect, and work fine on multiple lines. If a declaration turns out to be not quite what you wanted, you can just go back, edit it, and re-evaluate the code cell." ] @@ -354,11 +305,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -382,10 +329,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Although this doesn't hold everywhere, we've tried to keep IHaskell relatively similar to GHCi in terms of naming. So, just like in GHCi, you can inspect types with `:type` (or shorthands):" ] @@ -393,11 +337,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -500,10 +440,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The same goes for the `:info` command. However, unlike GHCi, which simply prints info, the IHaskell notebook brings up a separate pane." ] @@ -511,11 +448,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -530,10 +463,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane that pops up after this is evaluated. However, you can disable the interactive pager, and instead just show the output below the cell:" ] @@ -541,11 +471,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- Only takes effect on later cells, so stick it in its own cell.\n", @@ -555,11 +481,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -691,10 +613,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "We can now write slightly more complicated scripts." ] @@ -702,11 +621,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -734,10 +649,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "This is where the similarities with GHCi end, and the particularly shiny features of IHaskell begin.\n", "\n", @@ -747,11 +659,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "data Color = Red | Green | Blue" @@ -759,10 +667,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If we were playing around with designing GUI applications, for instance, we might want to actually *see* these colors, instead of just seeing the text \"Red\", \"Green\", and \"Blue\" when we are debugging.\n", "\n", @@ -772,11 +677,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import IHaskell.Display\n", @@ -794,10 +695,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Once we define a custom `display :: a -> IO Display` function, we can simply output a `Color`:" ] @@ -805,11 +703,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1090,10 +984,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `DisplayData` type has several constructors which let you display your data as plain text, HTML, images (SVG, PNG, JPG), or even as LaTeX code.\n", "\n", @@ -1104,10 +995,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-aeson` package adds a display for [Aeson](http://hackage.haskell.org/package/aeson) JSON `Value` types. These are automatically formatted as JSON, rather than as Haskell values:" ] @@ -1115,16 +1003,12 @@ { "cell_type": "code", "execution_count": 17, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "null" + "Null" ] }, "metadata": {}, @@ -1133,7 +1017,7 @@ { "data": { "text/plain": [ - "true" + "Bool True" ] }, "metadata": {}, @@ -1142,10 +1026,7 @@ { "data": { "text/plain": [ - "{\n", - " \"x\": 3,\n", - " \"y\": 2\n", - "}" + "Object (fromList [(\"x\",Number 3.0),(\"y\",Number 2.0)])" ] }, "metadata": {}, @@ -1169,10 +1050,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-blaze` package lets you play around with HTML straight from within IHaskell using the [Blaze](http://jaspervdj.be/blaze/tutorial.html) library." ] @@ -1180,11 +1058,7 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1270,125 +1144,12 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "
\n", - "

\n", - " This is an example of BlazeMarkup syntax.\n", - "

\n", - " \n", - " Hello\n", - " \n", - "
\n" + "<interactive>:1:1: error:
Could not find module ‘Text.Blaze.Html4.Strict’
" ], "text/plain": [ - "
\n", - "

\n", - " This is an example of BlazeMarkup syntax.\n", - "

\n", - " \n", - " Hello\n", - " \n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "\n", - "\n", - "\n", - "\n", - "" + ":1:1: error:\n", + " Could not find module ‘Text.Blaze.Html4.Strict’\n", + " Use -v to see a list of the files searched for." ] }, "metadata": {}, @@ -1413,10 +1174,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-diagrams` package allows you to experiment with the [diagrams](http://projects.haskell.org/diagrams/) package. It requires the Cairo backend." ] @@ -1424,15 +1182,99 @@ { "cell_type": "code", "execution_count": 19, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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" + "text/html": [ + "<interactive>:1:1: error:
Could not find module ‘Diagrams.Prelude’
" + ], + "text/plain": [ + ":1:1: error:\n", + " Could not find module ‘Diagrams.Prelude’\n", + " Use -v to see a list of the files searched for." + ] }, "metadata": {}, "output_type": "display_data" @@ -1461,10 +1303,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Just like with Diagrams, `ihaskell-charts` allows you to use the [Chart](https://github.com/timbod7/haskell-chart/wiki) library for plotting from within IHaskell. (You will need to install `cairo` as well, which may be a bit of a hassle.)" ] @@ -1472,15 +1311,99 @@ { "cell_type": "code", "execution_count": 20, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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" + "text/html": [ + "<interactive>:1:1: error:
Could not find module ‘Graphics.Rendering.Chart’
" + ], + "text/plain": [ + ":1:1: error:\n", + " Could not find module ‘Graphics.Rendering.Chart’\n", + " Use -v to see a list of the files searched for." + ] }, "metadata": {}, "output_type": "display_data" @@ -1514,10 +1437,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to displaying outputs in a rich format, IHaskell has a bunch of useful features.\n", "\n", @@ -1527,11 +1447,7 @@ { "cell_type": "code", "execution_count": 21, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1668,10 +1584,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you're an experienced Haskeller, though, and don't want `hlint` telling you what to do, you can easily turn it off:" ] @@ -1679,11 +1592,7 @@ { "cell_type": "code", "execution_count": 22, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- If hlint annoys you, though, you can turn it off.\n", @@ -1694,11 +1603,7 @@ { "cell_type": "code", "execution_count": 23, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1717,10 +1622,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to `hlint` integration, IHaskell also integrates **Hoogle** for documentation searches. IHaskell provides two directives for searching Hoogle. The first of these, `:document` (or shorthands), looks for exact matches." ] @@ -1728,11 +1630,7 @@ { "cell_type": "code", "execution_count": 24, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -1823,14 +1721,289 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a](package base, module Control.Monad)
This generalizes the list-based filter function. \n", + "filterM ∷ Applicative m ⇒ (a → m Bool) → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle v a → Bundle m v a
Yield a monadic stream of elements that satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle m v a → Bundle m v a
Drop elements which do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Stream m a → Stream m a
Drop elements which do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Vector v a) ⇒ (a → m Bool) → v a → m (v a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Prim a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Storable a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Unbox a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → ConduitT a a m ()
Keep only values in the stream passing a given monadic predicate.\n", + "
\n", + "
\n", + "
Subject to fusion\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Pipe a a m r
(filterM predicate) only forwards values that satisfy the\n", + "
\n", + "
monadic predicate\n", + "
\n", + "
\n", + "
\n",
+       "
\n", + "
filterM (pure (pure True)) = cat\n", + "
\n", + "
\n", + "
filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n", + "
\n", + "
\n", + "
\n", + "
\n", + "filterM ∷ (a → IO Bool) → InputStream a → IO (InputStream a)
Drops chunks from an input stream if they fail to match a given filter\n", + "
\n", + "
predicate. See filter.\n", + "
\n", + "
\n", + "
Items pushed back to the returned stream are propagated back upstream.\n", + "
\n", + "
\n", + "
Example:\n", + "
\n", + "
\n", + "
\n",
+       "
\n", + "
ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n", + "
\n", + "
Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n", + "
\n", + "
[\"the\",\"quick\",\"fox\"]\n", + "
\n", + "
\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ (IsSequence seq, Monad m) ⇒ (Element seq → m Bool) → seq → m seq
The monadic version of filter.\n", + "
\n", + "
\n", + "filterM ∷ (Monad m) ⇒ (a → m Bool) → Stream (Of a) m r → Stream (Of a) m r
Skip elements of a stream that fail a monadic test\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Vector v a) ⇒ a → m Bool → v a → m v a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Storable a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Unbox a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a]
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ (Applicative f) ⇒ (a → f Bool) → [a] → f [a]
See mapM.\n", + "
\n", + "
\n", + "filterM ∷ (Monad m, Vector u a, Vector v b) ⇒ ((a, b) → m Bool) → Vector u v (a, b) → m (Vector u v (a, b))
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "
\n", + "filterM ∷ (IsStream t, Monad m) ⇒ (a → m Bool) → t m a → t m a
Same as filter but with a monadic predicate.\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", "
\n", "
\n" ], "text/plain": [ + "filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Bundle v a -> Bundle m v a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle.html#v:filterM\n", + "Yield a monadic stream of elements that satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Bundle m v a -> Bundle m v a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle-Monadic.html#v:filterM\n", + "Drop elements which do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Stream-Monadic.html#v:filterM\n", + "Drop elements which do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Vector v a) => (a -> m Bool) -> v a -> m (v a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Prim a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Primitive.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Storable a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Storable.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Unbox a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> ConduitT a a m ()\n", + "URL: https://hackage.haskell.org/package/conduit/docs/Data-Conduit-Combinators.html#v:filterM\n", + "Keep only values in the stream passing a given monadic predicate.\n", + "\n", + "Subject to fusion\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Pipe a a m r\n", + "URL: https://hackage.haskell.org/package/pipes/docs/Pipes-Prelude.html#v:filterM\n", + "(filterM predicate) only forwards values that satisfy the\n", + "monadic predicate\n", + "\n", + "
\n",
+       "filterM (pure (pure True)) = cat\n",
+       "\n",
+       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
+       "
\n", + "\n", + "filterM :: (a -> IO Bool) -> InputStream a -> IO (InputStream a)\n", + "URL: https://hackage.haskell.org/package/io-streams/docs/System-IO-Streams-Combinators.html#v:filterM\n", + "Drops chunks from an input stream if they fail to match a given filter\n", + "predicate. See filter.\n", + "\n", + "Items pushed back to the returned stream are propagated back upstream.\n", + "\n", + "Example:\n", + "\n", + "
\n",
+       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
+       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
+       "[\"the\",\"quick\",\"fox\"]\n",
+       "
\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude-Monad.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (IsSequence seq, Monad m) => (Element seq -> m Bool) -> seq -> m seq\n", + "URL: https://hackage.haskell.org/package/mono-traversable/docs/Data-Sequences.html#v:filterM\n", + "The monadic version of filter.\n", + "\n", + "filterM :: (Monad m) => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m r\n", + "URL: https://hackage.haskell.org/package/streaming/docs/Streaming-Prelude.html#v:filterM\n", + "Skip elements of a stream that fail a monadic test\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (Monad m, Vector v a) => a -> m Bool -> v a -> m v a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Boxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Storable a) => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Storable.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Unbox a) => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Unboxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", "filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]\n", - "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:filterM\n", - "This generalizes the list-based filter function." + "URL: https://hackage.haskell.org/package/yjtools/docs/Control-Monad-Tools.html#v:filterM\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/universum/docs/Universum-Monad-Reexport.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (Applicative f) => (a -> f Bool) -> [a] -> f [a]\n", + "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:filterM\n", + "See mapM.\n", + "\n", + "filterM :: (Monad m, Vector u a, Vector v b) => ((a, b) -> m Bool) -> Vector u v (a, b) -> m (Vector u v (a, b))\n", + "URL: https://hackage.haskell.org/package/hybrid-vectors/docs/Data-Vector-Hybrid.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a\n", + "URL: https://hackage.haskell.org/package/streamly/docs/Streamly-Prelude.html#v:filterM\n", + "Same as filter but with a monadic predicate.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/control-monad-free/docs/Control-Monad-Free.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/relude/docs/Relude-Monad-Reexport.html#v:filterM\n", + "This generalizes the list-based filter function." ] }, "metadata": {}, @@ -1843,10 +2016,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature. This will show you documentation for things that match the desired type signature, as demonstrated below. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations." ] @@ -1854,11 +2024,7 @@ { "cell_type": "code", "execution_count": 25, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -1949,281 +2115,1187 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "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", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\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", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", - "
\n", - "
For example,\n", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", - "
\n", - "
> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
We can combine multiple primitives using >*< multiple times.\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", + "zipExact ∷ Partial ⇒ [a] → [b] → [(a, b)]
\n",
+       "zipExact xs ys =\n",
+       "| length xs == length ys = zip xs ys\n",
+       "| otherwise              = error \"some message\"\n",
+       "
\n", "
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "shrinkState ∷ ShrinkState s a ⇒ a → s → [(a, s)](package QuickCheck, module Test.QuickCheck.Modifiers)
\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", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
* The entire string prior to the kth match (i.e. the prefix)\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
* The kth match, followed by the remainder of the string\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
Examples:\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
The needle parameter may not be empty. \n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "(+*+) ∷ [a] → [b] → [(a, b)]
Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", + "lists, produce a single list such that whenever v and\n", + "w have finite indices in the input lists, (v,w) has\n", + "finite index in the output list. Lower indices occur as the\n", + "fst part of the tuple more frequently, but not exponentially\n", + "so.\n", "
\n", + "unfairCartesianProduct ∷ [a] → [b] → [(a, b)]
Very unfair 2-way Cartesian product: same guarantee as the slightly\n", + "unfair one, except that lower indices may occur as the fst\n", + "part of the tuple exponentially more frequently. This mainly exists as\n", + "a specification to test against.\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", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
* The entire string prior to the kth match (i.e. the prefix)\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
* The kth match, followed by the remainder of the string\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
Examples:\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
This function is strict in its first argument, and lazy in its second.\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
The needle parameter may not be empty. \n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "genLNodes ∷ Enum a ⇒ a → Int → [LNode a](package fgl, module Data.Graph.Inductive.Example)
generate list of labeled nodes \n", + "zipLazy ∷ [a] → [b] → [(a, b)]
zipLazy is a kind of zip that is lazy in the second list\n", + "(observe the ~)\n", "
\n", + "concurrently ∷ MonadBaseControl IO m ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\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", + "concurrently ∷ ∀ m a b . (MonadBaseControl IO m, Forall (Pure m)) ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\n", "
\n", + "pairADefault ∷ Applicative f ⇒ f a → f b → f (a, b)
Default '>*< implementation for non-invertible\n", + "Applicatives.\n", "
\n", - "threadList ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", - "threadList' ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", - "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", "
\n", + "pair ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
Pair two samples. It's like zip but requires that both samples\n", + "have equal size.\n", "
\n", - "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", "
\n", + "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", - "mapAccumR ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", + "zip ∷ Sequence s ⇒ s a → s b → s (a, b)
Combine two sequences into a sequence of pairs. If the sequences are\n", + "different lengths, the excess elements of the longer sequence is\n", + "discarded.\n", + "\n", + "
\n",
+       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
+       "where j = min {n,m}\n",
+       "
\n", + "\n", + "Axioms:\n", + "\n", + "
    \n", + "
  • zip xs ys = zipWith (,) xs ys
  • \n", + "
\n", + "\n", + "This function is always unambiguous.\n", + "\n", + "Default running time: O( min( n1, n2 ) )\n", "
\n", - "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "zipUsingLview ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", + "zipUsingLists ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", + "concurrently ∷ MonadConc m ⇒ m a → m b → m (a, b)
Run two MonadConc actions concurrently, and return both\n", + "results. If either action throws an exception at any time, then the\n", + "other action is cancelled, and the exception is re-thrown by\n", + "concurrently.\n", + "\n", + "
\n",
+       "concurrently left right =\n",
+       "withAsync left $ \\a ->\n",
+       "withAsync right $ \\b ->\n",
+       "waitBoth a b\n",
+       "
\n", "
\n", + "mzipRep ∷ Representable f ⇒ f a → f b → f (a, b)
\n", + "box ∷ Graph g ⇒ g a → g b → g (a, b)
Compute the Cartesian product of graphs. Complexity: O(s1 *\n", + "s2) time, memory and size, where s1 and s2 are the\n", + "sizes of the given graphs.\n", + "\n", + "
\n",
+       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
+       ", ((0,'a'), (1,'a'))\n",
+       ", ((0,'b'), (1,'b'))\n",
+       ", ((1,'a'), (1,'b')) ]\n",
+       "
\n", + "\n", + "Up to an isomorphism between the resulting vertex types, this\n", + "operation is commutative, associative,\n", + "distributes over overlay, has singleton graphs as\n", + "identities and empty as the annihilating zero.\n", + "Below ~~ stands for the equality up to an isomorphism, e.g.\n", + "(x, ()) ~~ x.\n", + "\n", + "
\n",
+       "box x y               ~~ box y x\n",
+       "box x (box y z)       ~~ box (box x y) z\n",
+       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
+       "box x (vertex ())     ~~ x\n",
+       "box x empty           ~~ empty\n",
+       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
+       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
+       "
\n", "
\n", - "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
+       "divided = divide id\n",
+       "
\n", "
\n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
The RecordInputType divisible (contravariant) functor allows\n", + "you to build an InputType injector for a Dhall record.\n", + "\n", + "For example, let's take the following Haskell data type:\n", + "\n", + "
\n",
+       "data Project = Project\n",
+       "{ projectName :: Text\n",
+       ", projectDescription :: Text\n",
+       ", projectStars :: Natural\n",
+       "}\n",
+       "
\n", + "\n", + "And assume that we have the following Dhall record that we would like\n", + "to parse as a Project:\n", + "\n", + "
\n",
+       "{ name =\n",
+       "\"dhall-haskell\"\n",
+       ", description =\n",
+       "\"A configuration language guaranteed to terminate\"\n",
+       ", stars =\n",
+       "289\n",
+       "}\n",
+       "
\n", + "\n", + "Our injector has type InputType Project, but we can't\n", + "build that out of any smaller injectors, as InputTypes cannot\n", + "be combined (they are only Contravariants). However, we can use\n", + "an InputRecordType to build an InputType for\n", + "Project:\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputFieldWith \"name\" inject\n",
+       ">*< inputFieldWith \"description\" inject\n",
+       ">*< inputFieldWith \"stars\" inject\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Or, since we are simply using the Inject instance to inject\n", + "each field, we could write\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputField \"name\"\n",
+       ">*< inputField \"description\"\n",
+       ">*< inputField \"stars\"\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Infix divided\n", "
\n", - "mapAccumR ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
+       "divided = divide id\n",
+       "
\n", "
\n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", - "mapAccumL ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", + "contrazip2 ∷ Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", + "contrazip2 ∷ ∀ f a1 a2 . Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", + "pair ∷ Sized f ⇒ f a → f b → f (a, b)
Default: pair a b = (,) $ a * b.\n", "
\n", - "mapAccumR ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", - "
\n", - "
\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", - "breakSubstring ∷ ByteString → ByteString → (ByteString, ByteString)(package bytestring, module Data.ByteString)
otherwise -> Just (length x) \n", - "
\n", - "
\n", - "
For example, to tokenise a string, dropping delimiters:\n", - "
\n", - "
\n", - "
> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", - "> \n", - "
\n", - "
\n", - "
To skip to the first occurence of a string:\n", - "
\n", - "
\n", - "
> snd (breakSubstring x y)\n", - "
\n", - "
\n", - "
To take the parts of a string before a delimiter:\n", - "
\n", - "
\n", - "
> fst (breakSubstring x y) \n", - "
\n", - "
\n", - "breakOn ∷ Text → Text → (Text, Text)(package text, module Data.Text)
O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", - "
\n", - "
\n", - "
Examples:\n", - "
\n", - "
\n", - "
> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", - "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", - "
\n", - "
\n", - "
Laws:\n", - "
\n", - "
\n", - "
> append prefix match == haystack\n", - "> \n", - "
\n", - "
\n", - "
If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", - "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m). \n", - "
\n", - "
\n" - ], - "text/plain": [ - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:zip\n", - "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", - "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", - "A pairing/concatenation operator for builder primitives, both bounded and fixed size.\n", + "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
A pairing/concatenation operator for builder primitives, both bounded\n", + "and fixed size.\n", "\n", "For example,\n", "\n", - "> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
+       "
\n", "\n", - "We can combine multiple primitives using >*< multiple times.\n", + "We can combine multiple primitives using >*< multiple\n", + "times.\n", "\n", - "> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", - "shrinkState :: ShrinkState s a => a -> s -> [(a, s)]\n", - "URL: http://hackage.haskell.org/packages/archive/QuickCheck/latest/doc/html/Test-QuickCheck-Modifiers.html#v:shrinkState\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
+       "
\n", + "
\n", + "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
Merge two functors into a tuple, analogous to liftA2\n", + "(,). (Sometimes known as **.)\n", + "
\n", + "zip ∷ List l ⇒ l a → l b → l (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "zip ∷ (Zip f) ⇒ f a → f b → f (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "mzip ∷ MonadZip m ⇒ m a → m b → m (a, b)
\n", + "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "biunfold ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Given a way to generate elements, return a way to generate structures\n", + "containing those elements.\n", + "
\n", + "biunfoldBF ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Breadth-first unfold, which orders the result by the number of\n", + "choose calls.\n", + "
\n", + "deserializeWith2 ∷ (Serial2 f, MonadGet m) ⇒ m a → m b → m (f a b)
\n", + "biunfoldRestrict ∷ (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) ⇒ f a → f b → f (t a b)
\n", + "biunfoldRestrictBF ∷ (BiunfoldableR p q t, Unfolder f, p a, q b) ⇒ f a → f b → f (t a b)
\n", + "mesh ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a mesh graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", "\n", - "breakOnAll :: Text -> Text -> [(Text, Text)]\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOnAll\n", - "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "
\n",
+       "mesh xs     []   == empty\n",
+       "mesh []     ys   == empty\n",
+       "mesh [x]    [y]  == vertex (x, y)\n",
+       "mesh xs     ys   == box (path xs) (path ys)\n",
+       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
+       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
+       "
\n", + "
\n", + "torus ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a torus graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", "\n", - "* The entire string prior to the kth match (i.e. the prefix)\n", - "* The kth match, followed by the remainder of the string\n", + "
\n",
+       "torus xs    []   == empty\n",
+       "torus []    ys   == empty\n",
+       "torus [x]   [y]  == edge (x,y) (x,y)\n",
+       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
+       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
+       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
+       "
\n", + "
\n", + "zipExactMay ∷ [a] → [b] → Maybe [(a, b)]
\n" + ], + "text/plain": [ + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "Examples:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "The needle parameter may not be empty. \n", - "breakOnAll :: Text -> Text -> [(Text, Text)]\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text-Lazy.html#v:breakOnAll\n", - "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "zip is right-lazy:\n", "\n", - "* The entire string prior to the kth match (i.e. the prefix)\n", - "* The kth match, followed by the remainder of the string\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "Examples:\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/Data-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "This function is strict in its first argument, and lazy in its second.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "The needle parameter may not be empty. \n", - "genLNodes :: Enum a => a -> Int -> [LNode a]\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Example.html#v:genLNodes\n", - "generate list of labeled nodes \n", - "gmapAccumT :: Data d => (forall e. Data e => a -> e -> (a, e)) -> a -> d -> (a, d)\n", - "URL: http://hackage.haskell.org/packages/archive/syb/latest/doc/html/Data-Generics-Twins.html#v:gmapAccumT\n", - "gmapT with accumulation \n", - "threadList :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList\n", + "zip is right-lazy:\n", "\n", - "threadList' :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList-39-\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", - "mapAccumR :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy-Char8.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", - "mapAccumR :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumL\n", - "O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", - "mapAccumR :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", - "execRWS :: RWS r w s a -> r -> s -> (s, w)\n", - "URL: http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html#v:execRWS\n", - "Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n", - "breakSubstring :: ByteString -> ByteString -> (ByteString, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:breakSubstring\n", - "otherwise -> Just (length x) \n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/GHC-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "For example, to tokenise a string, dropping delimiters:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", - "> \n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "To skip to the first occurence of a string:\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "> snd (breakSubstring x y)\n", + "zip is right-lazy:\n", "\n", - "To take the parts of a string before a delimiter:\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "> fst (breakSubstring x y) \n", - "breakOn :: Text -> Text -> (Text, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOn\n", - "O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/GHC-OldList.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "Examples:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", - "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "Laws:\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "> append prefix match == haystack\n", - "> \n", + "zip is right-lazy:\n", "\n", - "If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m)." + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/hspec/docs/Test-Hspec-Discover.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zipExact :: Partial => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExact\n", + "
\n",
+       "zipExact xs ys =\n",
+       "| length xs == length ys = zip xs ys\n",
+       "| otherwise              = error \"some message\"\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base-compat/docs/Prelude-Compat.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude-Base.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/fay-base/docs/Prelude.html#v:zip\n", + "\n", + "(+*+) :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:-43--42--43-\n", + "Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", + "lists, produce a single list such that whenever v and\n", + "w have finite indices in the input lists, (v,w) has\n", + "finite index in the output list. Lower indices occur as the\n", + "fst part of the tuple more frequently, but not exponentially\n", + "so.\n", + "\n", + "unfairCartesianProduct :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:unfairCartesianProduct\n", + "Very unfair 2-way Cartesian product: same guarantee as the slightly\n", + "unfair one, except that lower indices may occur as the fst\n", + "part of the tuple exponentially more frequently. This mainly exists as\n", + "a specification to test against.\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universum/docs/Universum-List-Reexport.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/prelude-compat/docs/Data-List2010.html#v:zip\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/prelude-compat/docs/Prelude2010.html#v:zip\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq-ListSeq.html#v:zip\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/intro/docs/Intro.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/relude/docs/Relude-List-Reexport.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zipLazy :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/ghc/docs/Util.html#v:zipLazy\n", + "zipLazy is a kind of zip that is lazy in the second list\n", + "(observe the ~)\n", + "\n", + "concurrently :: MonadBaseControl IO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted.html#v:concurrently\n", + "Generalized version of concurrently.\n", + "\n", + "concurrently :: forall m a b . (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted-Safe.html#v:concurrently\n", + "Generalized version of concurrently.\n", + "\n", + "pairADefault :: Applicative f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:pairADefault\n", + "Default '>*< implementation for non-invertible\n", + "Applicatives.\n", + "\n", + "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:zip\n", + "O(min(m,n)) Zip two vectors\n", + "\n", + "pair :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/statistics/docs/Statistics-Sample.html#v:pair\n", + "Pair two samples. It's like zip but requires that both samples\n", + "have equal size.\n", + "\n", + "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:zip\n", + "O(min(m,n)) Zip two vectors\n", + "\n", + "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/unliftio/docs/UnliftIO-Async.html#v:concurrently\n", + "Unlifted concurrently.\n", + "\n", + "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/yesod-websockets/docs/Yesod-WebSockets.html#v:concurrently\n", + "Unlifted concurrently.\n", + "\n", + "zip :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq.html#v:zip\n", + "Combine two sequences into a sequence of pairs. If the sequences are\n", + "different lengths, the excess elements of the longer sequence is\n", + "discarded.\n", + "\n", + "
\n",
+       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
+       "where j = min {n,m}\n",
+       "
\n", + "\n", + "Axioms:\n", + "\n", + "
    \n", + "
  • zip xs ys = zipWith (,) xs ys
  • \n", + "
\n", + "\n", + "This function is always unambiguous.\n", + "\n", + "Default running time: O( min( n1, n2 ) )\n", + "\n", + "zipUsingLview :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLview\n", + "\n", + "zipUsingLists :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLists\n", + "\n", + "concurrently :: MonadConc m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/concurrency/docs/Control-Concurrent-Classy-Async.html#v:concurrently\n", + "Run two MonadConc actions concurrently, and return both\n", + "results. If either action throws an exception at any time, then the\n", + "other action is cancelled, and the exception is re-thrown by\n", + "concurrently.\n", + "\n", + "
\n",
+       "concurrently left right =\n",
+       "withAsync left $ \\a ->\n",
+       "withAsync right $ \\b ->\n",
+       "waitBoth a b\n",
+       "
\n", + "\n", + "mzipRep :: Representable f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/adjunctions/docs/Data-Functor-Rep.html#v:mzipRep\n", + "\n", + "box :: Graph g => g a -> g b -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:box\n", + "Compute the Cartesian product of graphs. Complexity: O(s1 *\n", + "s2) time, memory and size, where s1 and s2 are the\n", + "sizes of the given graphs.\n", + "\n", + "
\n",
+       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
+       ", ((0,'a'), (1,'a'))\n",
+       ", ((0,'b'), (1,'b'))\n",
+       ", ((1,'a'), (1,'b')) ]\n",
+       "
\n", + "\n", + "Up to an isomorphism between the resulting vertex types, this\n", + "operation is commutative, associative,\n", + "distributes over overlay, has singleton graphs as\n", + "identities and empty as the annihilating zero.\n", + "Below ~~ stands for the equality up to an isomorphism, e.g.\n", + "(x, ()) ~~ x.\n", + "\n", + "
\n",
+       "box x y               ~~ box y x\n",
+       "box x (box y z)       ~~ box (box x y) z\n",
+       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
+       "box x (vertex ())     ~~ x\n",
+       "box x empty           ~~ empty\n",
+       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
+       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
+       "
\n", + "\n", + "divided :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/contravariant/docs/Data-Functor-Contravariant-Divisible.html#v:divided\n", + "
\n",
+       "divided = divide id\n",
+       "
\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/dhall/docs/Dhall.html#v:-62--42--60-\n", + "The RecordInputType divisible (contravariant) functor allows\n", + "you to build an InputType injector for a Dhall record.\n", + "\n", + "For example, let's take the following Haskell data type:\n", + "\n", + "
\n",
+       "data Project = Project\n",
+       "{ projectName :: Text\n",
+       ", projectDescription :: Text\n",
+       ", projectStars :: Natural\n",
+       "}\n",
+       "
\n", + "\n", + "And assume that we have the following Dhall record that we would like\n", + "to parse as a Project:\n", + "\n", + "
\n",
+       "{ name =\n",
+       "\"dhall-haskell\"\n",
+       ", description =\n",
+       "\"A configuration language guaranteed to terminate\"\n",
+       ", stars =\n",
+       "289\n",
+       "}\n",
+       "
\n", + "\n", + "Our injector has type InputType Project, but we can't\n", + "build that out of any smaller injectors, as InputTypes cannot\n", + "be combined (they are only Contravariants). However, we can use\n", + "an InputRecordType to build an InputType for\n", + "Project:\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputFieldWith \"name\" inject\n",
+       ">*< inputFieldWith \"description\" inject\n",
+       ">*< inputFieldWith \"stars\" inject\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Or, since we are simply using the Inject instance to inject\n", + "each field, we could write\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputField \"name\"\n",
+       ">*< inputField \"description\"\n",
+       ">*< inputField \"stars\"\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Infix divided\n", + "\n", + "divided :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:divided\n", + "
\n",
+       "divided = divide id\n",
+       "
\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:-62--42--60-\n", + "An alias to divided.\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras.html#v:-62--42--60-\n", + "An alias to divided.\n", + "\n", + "contrazip2 :: Divisible f => f a1 -> f a2 -> f (a1, a2)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:contrazip2\n", + "\n", + "contrazip2 :: forall f a1 a2 . Divisible f => f a1 -> f a2 -> f (a1, a2)\n", + "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras-Contrazip.html#v:contrazip2\n", + "\n", + "pair :: Sized f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/size-based/docs/Control-Sized.html#v:pair\n", + "Default: pair a b = (,) $ a * b.\n", + "\n", + "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/bytestring/docs/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", + "A pairing/concatenation operator for builder primitives, both bounded\n", + "and fixed size.\n", + "\n", + "For example,\n", + "\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
+       "
\n", + "\n", + "We can combine multiple primitives using >*< multiple\n", + "times.\n", + "\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
+       "
\n", + "\n", + "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:-62--42--60-\n", + "Merge two functors into a tuple, analogous to liftA2\n", + "(,). (Sometimes known as **.)\n", + "\n", + "zip :: List l => l a -> l b -> l (a, b)\n", + "URL: https://hackage.haskell.org/package/List/docs/Data-List-Class.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/classy-prelude/docs/ClassyPrelude.html#v:zip\n", + "\n", + "zip :: (Zip f) => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/non-empty/docs/Data-NonEmpty-Class.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/keys/docs/Data-Key.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/chunked-data/docs/Data-ChunkedZip.html#v:zip\n", + "\n", + "mzip :: MonadZip m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/base/docs/Control-Monad-Zip.html#v:mzip\n", + "\n", + "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:projectZip\n", + "Zipping projections.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:projectZip\n", + "Zipping projections.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-record/docs/Database-Relational-Documentation.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "biunfold :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfold\n", + "Given a way to generate elements, return a way to generate structures\n", + "containing those elements.\n", + "\n", + "biunfoldBF :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfoldBF\n", + "Breadth-first unfold, which orders the result by the number of\n", + "choose calls.\n", + "\n", + "deserializeWith2 :: (Serial2 f, MonadGet m) => m a -> m b -> m (f a b)\n", + "URL: https://hackage.haskell.org/package/bytes/docs/Data-Bytes-Serial.html#v:deserializeWith2\n", + "\n", + "biunfoldRestrict :: (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrict\n", + "\n", + "biunfoldRestrictBF :: (BiunfoldableR p q t, Unfolder f, p a, q b) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrictBF\n", + "\n", + "mesh :: Graph g => [a] -> [b] -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:mesh\n", + "Construct a mesh graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", + "\n", + "
\n",
+       "mesh xs     []   == empty\n",
+       "mesh []     ys   == empty\n",
+       "mesh [x]    [y]  == vertex (x, y)\n",
+       "mesh xs     ys   == box (path xs) (path ys)\n",
+       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
+       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
+       "
\n", + "\n", + "torus :: Graph g => [a] -> [b] -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:torus\n", + "Construct a torus graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", + "\n", + "
\n",
+       "torus xs    []   == empty\n",
+       "torus []    ys   == empty\n",
+       "torus [x]   [y]  == edge (x,y) (x,y)\n",
+       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
+       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
+       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
+       "
\n", + "\n", + "zipExactMay :: [a] -> [b] -> Maybe [(a, b)]\n", + "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExactMay" ] }, "metadata": {}, @@ -2236,10 +3308,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you need a refresher on all of the options, you can just use `:help`:" ] @@ -2247,11 +3316,7 @@ { "cell_type": "code", "execution_count": 26, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2288,10 +3353,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "All of the code you normally put into IHaskell is (like in GHCi) interpreted. However, sometimes you've perfected a function, and now need it to run faster. In that case, you can go ahead and define a module in a single cell. As long as your module has a module header along the lines of `module Name where`, IHaskell will recognize it as a module. It will create the file `A/B.hs`, compile it, and load it. " ] @@ -2299,11 +3361,7 @@ { "cell_type": "code", "execution_count": 27, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- If your code isn't running fast enough, you can just put it into a module.\n", @@ -2316,10 +3374,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Note that the module is by default imported unqualified, as though you had typed `import A.B`." ] @@ -2327,11 +3382,7 @@ { "cell_type": "code", "execution_count": 28, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2360,10 +3411,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Note that since a new module is imported, all previous bound identifiers are now unbound. For instance, we no longer have access to the `f` function from before:" ] @@ -2371,11 +3419,7 @@ { "cell_type": "code", "execution_count": 29, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2477,10 +3521,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "However, if you re-import this module with another import statement, the original implicit import goes away." ] @@ -2488,11 +3529,7 @@ { "cell_type": "code", "execution_count": 30, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2522,10 +3559,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Thanks!\n", "---\n", @@ -2549,7 +3583,8 @@ "codemirror_mode": "ihaskell", "file_extension": ".hs", "name": "haskell", - "version": "8.0.2" + "pygments_lexer": "Haskell", + "version": "8.4.3" }, "latex_envs": { "bibliofile": "biblio.bib", @@ -2570,5 +3605,5 @@ } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From afb05614f47fcba95de05308bb90a4ac9b3f991a Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Thu, 1 Nov 2018 21:43:09 +0100 Subject: [PATCH 07/10] Revert "Update notebook: hoogle response changed." This reverts commit 31a59439ac059e8852f712c2176b22115d93457e. --- notebooks/IHaskell.ipynb | 2207 ++++++++++---------------------------- 1 file changed, 586 insertions(+), 1621 deletions(-) diff --git a/notebooks/IHaskell.ipynb b/notebooks/IHaskell.ipynb index 7ef7edfe..2818d75f 100644 --- a/notebooks/IHaskell.ipynb +++ b/notebooks/IHaskell.ipynb @@ -2,7 +2,10 @@ "cells": [ { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "![](https://camo.githubusercontent.com/f6540337202bb3b0c2545d90de0791c9196f9510/68747470733a2f2f7261772e6769746875622e636f6d2f67696269616e736b792f494861736b656c6c2f6d61737465722f68746d6c2f6c6f676f2d36347836342e706e67)\n", "\n", @@ -18,7 +21,11 @@ { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -47,7 +54,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "As you can see, each input cell get an execution number. The first input cell is labeled `In [1]`. Just like in GHCi, the output of the last executed statement or expression is available via the `it` variable - however, in addition, the output of the $n$th cell is available via the `itN` variable. For example, if we wanted to see what the first cell printed, we can go ahead and output that:" ] @@ -55,7 +65,11 @@ { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -73,7 +87,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to simple code cells such as the ones you see, you can also have other types of cells. All of this inline text, for instance, is written using Markdown cells, which support the majority of Github markdown syntax. This lets you embed images and formatting and arbitrary HTML interspersed with your Haskell code. In addition, you can export these notebooks into HTML or even as presentations using `reveal.js`. \n", "\n", @@ -83,7 +100,11 @@ { "cell_type": "code", "execution_count": 3, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -106,7 +127,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to multi-line expressions, IHaskell supports most things that you could put in a standard Haskell file. For example, we can have function bindings without the `let` that GHCi requires. (As long as you group type signatures and their corresponding declarations together, you can use pattern matching and put signatures on your top-level declarations!)" ] @@ -114,7 +138,11 @@ { "cell_type": "code", "execution_count": 4, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -146,7 +174,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "So far we've just looked at pure functions, but nothing is stopping us from doing IO." ] @@ -154,7 +185,11 @@ { "cell_type": "code", "execution_count": 5, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -172,7 +207,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "IHaskell supports most GHC extensions via the `:extension` directive (or any shorthand thereof)." ] @@ -180,7 +218,11 @@ { "cell_type": "code", "execution_count": 6, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -287,7 +329,11 @@ { "cell_type": "code", "execution_count": 7, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- And enable extensions.\n", @@ -297,7 +343,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Data declarations do pretty much what you expect, and work fine on multiple lines. If a declaration turns out to be not quite what you wanted, you can just go back, edit it, and re-evaluate the code cell." ] @@ -305,7 +354,11 @@ { "cell_type": "code", "execution_count": 8, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -329,7 +382,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Although this doesn't hold everywhere, we've tried to keep IHaskell relatively similar to GHCi in terms of naming. So, just like in GHCi, you can inspect types with `:type` (or shorthands):" ] @@ -337,7 +393,11 @@ { "cell_type": "code", "execution_count": 9, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -440,7 +500,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The same goes for the `:info` command. However, unlike GHCi, which simply prints info, the IHaskell notebook brings up a separate pane." ] @@ -448,7 +511,11 @@ { "cell_type": "code", "execution_count": 10, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -463,7 +530,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane that pops up after this is evaluated. However, you can disable the interactive pager, and instead just show the output below the cell:" ] @@ -471,7 +541,11 @@ { "cell_type": "code", "execution_count": 11, - "metadata": {}, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- Only takes effect on later cells, so stick it in its own cell.\n", @@ -481,7 +555,11 @@ { "cell_type": "code", "execution_count": 12, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -613,7 +691,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "We can now write slightly more complicated scripts." ] @@ -621,7 +702,11 @@ { "cell_type": "code", "execution_count": 13, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -649,7 +734,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "This is where the similarities with GHCi end, and the particularly shiny features of IHaskell begin.\n", "\n", @@ -659,7 +747,11 @@ { "cell_type": "code", "execution_count": 14, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "data Color = Red | Green | Blue" @@ -667,7 +759,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If we were playing around with designing GUI applications, for instance, we might want to actually *see* these colors, instead of just seeing the text \"Red\", \"Green\", and \"Blue\" when we are debugging.\n", "\n", @@ -677,7 +772,11 @@ { "cell_type": "code", "execution_count": 15, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "import IHaskell.Display\n", @@ -695,7 +794,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Once we define a custom `display :: a -> IO Display` function, we can simply output a `Color`:" ] @@ -703,7 +805,11 @@ { "cell_type": "code", "execution_count": 16, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -984,7 +1090,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `DisplayData` type has several constructors which let you display your data as plain text, HTML, images (SVG, PNG, JPG), or even as LaTeX code.\n", "\n", @@ -995,7 +1104,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `ihaskell-aeson` package adds a display for [Aeson](http://hackage.haskell.org/package/aeson) JSON `Value` types. These are automatically formatted as JSON, rather than as Haskell values:" ] @@ -1003,12 +1115,16 @@ { "cell_type": "code", "execution_count": 17, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { "text/plain": [ - "Null" + "null" ] }, "metadata": {}, @@ -1017,7 +1133,7 @@ { "data": { "text/plain": [ - "Bool True" + "true" ] }, "metadata": {}, @@ -1026,7 +1142,10 @@ { "data": { "text/plain": [ - "Object (fromList [(\"x\",Number 3.0),(\"y\",Number 2.0)])" + "{\n", + " \"x\": 3,\n", + " \"y\": 2\n", + "}" ] }, "metadata": {}, @@ -1050,7 +1169,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `ihaskell-blaze` package lets you play around with HTML straight from within IHaskell using the [Blaze](http://jaspervdj.be/blaze/tutorial.html) library." ] @@ -1058,7 +1180,11 @@ { "cell_type": "code", "execution_count": 18, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -1144,12 +1270,125 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "<interactive>:1:1: error:
Could not find module ‘Text.Blaze.Html4.Strict’
" + "
\n", + "

\n", + " This is an example of BlazeMarkup syntax.\n", + "

\n", + " \n", + " Hello\n", + " \n", + "
\n" ], "text/plain": [ - ":1:1: error:\n", - " Could not find module ‘Text.Blaze.Html4.Strict’\n", - " Use -v to see a list of the files searched for." + "
\n", + "

\n", + " This is an example of BlazeMarkup syntax.\n", + "

\n", + " \n", + " Hello\n", + " \n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "\n", + "\n", + "\n", + "\n", + "" ] }, "metadata": {}, @@ -1174,7 +1413,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `ihaskell-diagrams` package allows you to experiment with the [diagrams](http://projects.haskell.org/diagrams/) package. It requires the Cairo backend." ] @@ -1182,99 +1424,15 @@ { "cell_type": "code", "execution_count": 19, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { - "text/html": [ - "<interactive>:1:1: error:
Could not find module ‘Diagrams.Prelude’
" - ], - "text/plain": [ - ":1:1: error:\n", - " Could not find module ‘Diagrams.Prelude’\n", - " Use -v to see a list of the files searched for." - ] + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1303,7 +1461,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Just like with Diagrams, `ihaskell-charts` allows you to use the [Chart](https://github.com/timbod7/haskell-chart/wiki) library for plotting from within IHaskell. (You will need to install `cairo` as well, which may be a bit of a hassle.)" ] @@ -1311,99 +1472,15 @@ { "cell_type": "code", "execution_count": 20, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { - "text/html": [ - "<interactive>:1:1: error:
Could not find module ‘Graphics.Rendering.Chart’
" - ], - "text/plain": [ - ":1:1: error:\n", - " Could not find module ‘Graphics.Rendering.Chart’\n", - " Use -v to see a list of the files searched for." - ] + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1437,7 +1514,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to displaying outputs in a rich format, IHaskell has a bunch of useful features.\n", "\n", @@ -1447,7 +1527,11 @@ { "cell_type": "code", "execution_count": 21, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -1584,7 +1668,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If you're an experienced Haskeller, though, and don't want `hlint` telling you what to do, you can easily turn it off:" ] @@ -1592,7 +1679,11 @@ { "cell_type": "code", "execution_count": 22, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- If hlint annoys you, though, you can turn it off.\n", @@ -1603,7 +1694,11 @@ { "cell_type": "code", "execution_count": 23, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -1622,7 +1717,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to `hlint` integration, IHaskell also integrates **Hoogle** for documentation searches. IHaskell provides two directives for searching Hoogle. The first of these, `:document` (or shorthands), looks for exact matches." ] @@ -1630,7 +1728,11 @@ { "cell_type": "code", "execution_count": 24, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -1721,289 +1823,14 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "filterM ∷ Applicative m ⇒ (a → m Bool) → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle v a → Bundle m v a
Yield a monadic stream of elements that satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle m v a → Bundle m v a
Drop elements which do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Stream m a → Stream m a
Drop elements which do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Vector v a) ⇒ (a → m Bool) → v a → m (v a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Prim a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Storable a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Unbox a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → ConduitT a a m ()
Keep only values in the stream passing a given monadic predicate.\n", - "
\n", - "
\n", - "
Subject to fusion\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Pipe a a m r
(filterM predicate) only forwards values that satisfy the\n", - "
\n", - "
monadic predicate\n", - "
\n", - "
\n", - "
\n",
-       "
\n", - "
filterM (pure (pure True)) = cat\n", - "
\n", - "
\n", - "
filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n", - "
\n", - "
\n", - "
\n", - "
\n", - "filterM ∷ (a → IO Bool) → InputStream a → IO (InputStream a)
Drops chunks from an input stream if they fail to match a given filter\n", - "
\n", - "
predicate. See filter.\n", - "
\n", - "
\n", - "
Items pushed back to the returned stream are propagated back upstream.\n", - "
\n", - "
\n", - "
Example:\n", - "
\n", - "
\n", - "
\n",
-       "
\n", - "
ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n", - "
\n", - "
Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n", - "
\n", - "
[\"the\",\"quick\",\"fox\"]\n", - "
\n", - "
\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ (IsSequence seq, Monad m) ⇒ (Element seq → m Bool) → seq → m seq
The monadic version of filter.\n", - "
\n", - "
\n", - "filterM ∷ (Monad m) ⇒ (a → m Bool) → Stream (Of a) m r → Stream (Of a) m r
Skip elements of a stream that fail a monadic test\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Vector v a) ⇒ a → m Bool → v a → m v a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Storable a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Unbox a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a]
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ (Applicative f) ⇒ (a → f Bool) → [a] → f [a]
See mapM.\n", - "
\n", - "
\n", - "filterM ∷ (Monad m, Vector u a, Vector v b) ⇒ ((a, b) → m Bool) → Vector u v (a, b) → m (Vector u v (a, b))
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "
\n", - "filterM ∷ (IsStream t, Monad m) ⇒ (a → m Bool) → t m a → t m a
Same as filter but with a monadic predicate.\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a](package base, module Control.Monad)
This generalizes the list-based filter function. \n", "
\n", "
\n" ], "text/plain": [ - "filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Bundle v a -> Bundle m v a\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle.html#v:filterM\n", - "Yield a monadic stream of elements that satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Bundle m v a -> Bundle m v a\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle-Monadic.html#v:filterM\n", - "Drop elements which do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Stream-Monadic.html#v:filterM\n", - "Drop elements which do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Vector v a) => (a -> m Bool) -> v a -> m (v a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Prim a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Primitive.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Storable a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Storable.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Unbox a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> ConduitT a a m ()\n", - "URL: https://hackage.haskell.org/package/conduit/docs/Data-Conduit-Combinators.html#v:filterM\n", - "Keep only values in the stream passing a given monadic predicate.\n", - "\n", - "Subject to fusion\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Pipe a a m r\n", - "URL: https://hackage.haskell.org/package/pipes/docs/Pipes-Prelude.html#v:filterM\n", - "(filterM predicate) only forwards values that satisfy the\n", - "monadic predicate\n", - "\n", - "
\n",
-       "filterM (pure (pure True)) = cat\n",
-       "\n",
-       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
-       "
\n", - "\n", - "filterM :: (a -> IO Bool) -> InputStream a -> IO (InputStream a)\n", - "URL: https://hackage.haskell.org/package/io-streams/docs/System-IO-Streams-Combinators.html#v:filterM\n", - "Drops chunks from an input stream if they fail to match a given filter\n", - "predicate. See filter.\n", - "\n", - "Items pushed back to the returned stream are propagated back upstream.\n", - "\n", - "Example:\n", - "\n", - "
\n",
-       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
-       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
-       "[\"the\",\"quick\",\"fox\"]\n",
-       "
\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/protolude/docs/Protolude-Monad.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: (IsSequence seq, Monad m) => (Element seq -> m Bool) -> seq -> m seq\n", - "URL: https://hackage.haskell.org/package/mono-traversable/docs/Data-Sequences.html#v:filterM\n", - "The monadic version of filter.\n", - "\n", - "filterM :: (Monad m) => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m r\n", - "URL: https://hackage.haskell.org/package/streaming/docs/Streaming-Prelude.html#v:filterM\n", - "Skip elements of a stream that fail a monadic test\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: (Monad m, Vector v a) => a -> m Bool -> v a -> m v a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => a -> m Bool -> Vector a -> m Vector a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Boxed.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Storable a) => a -> m Bool -> Vector a -> m Vector a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Storable.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Unbox a) => a -> m Bool -> Vector a -> m Vector a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Unboxed.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", "filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/yjtools/docs/Control-Monad-Tools.html#v:filterM\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/universum/docs/Universum-Monad-Reexport.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: (Applicative f) => (a -> f Bool) -> [a] -> f [a]\n", - "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:filterM\n", - "See mapM.\n", - "\n", - "filterM :: (Monad m, Vector u a, Vector v b) => ((a, b) -> m Bool) -> Vector u v (a, b) -> m (Vector u v (a, b))\n", - "URL: https://hackage.haskell.org/package/hybrid-vectors/docs/Data-Vector-Hybrid.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a\n", - "URL: https://hackage.haskell.org/package/streamly/docs/Streamly-Prelude.html#v:filterM\n", - "Same as filter but with a monadic predicate.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/control-monad-free/docs/Control-Monad-Free.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/relude/docs/Relude-Monad-Reexport.html#v:filterM\n", - "This generalizes the list-based filter function." + "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:filterM\n", + "This generalizes the list-based filter function." ] }, "metadata": {}, @@ -2016,7 +1843,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature. This will show you documentation for things that match the desired type signature, as demonstrated below. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations." ] @@ -2024,7 +1854,11 @@ { "cell_type": "code", "execution_count": 25, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -2115,1187 +1949,281 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", + "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", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", "
\n", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\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", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", + "
\n", + "
For example,\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
We can combine multiple primitives using >*< multiple times.\n", "
\n", - "zipExact ∷ Partial ⇒ [a] → [b] → [(a, b)]
\n",
-       "zipExact xs ys =\n",
-       "| length xs == length ys = zip xs ys\n",
-       "| otherwise              = error \"some message\"\n",
-       "
\n", + "
\n", + "
> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "shrinkState ∷ ShrinkState s a ⇒ a → s → [(a, s)](package QuickCheck, module Test.QuickCheck.Modifiers)
\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", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
* The entire string prior to the kth match (i.e. the prefix)\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
* The kth match, followed by the remainder of the string\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
Examples:\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "(+*+) ∷ [a] → [b] → [(a, b)]
Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", - "lists, produce a single list such that whenever v and\n", - "w have finite indices in the input lists, (v,w) has\n", - "finite index in the output list. Lower indices occur as the\n", - "fst part of the tuple more frequently, but not exponentially\n", - "so.\n", + "
\n", + "
The needle parameter may not be empty. \n", "
\n", - "unfairCartesianProduct ∷ [a] → [b] → [(a, b)]
Very unfair 2-way Cartesian product: same guarantee as the slightly\n", - "unfair one, except that lower indices may occur as the fst\n", - "part of the tuple exponentially more frequently. This mainly exists as\n", - "a specification to test against.\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\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", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
* The entire string prior to the kth match (i.e. the prefix)\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
* The kth match, followed by the remainder of the string\n", "
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
Examples:\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
This function is strict in its first argument, and lazy in its second.\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
The needle parameter may not be empty. \n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", "
\n", - "zipLazy ∷ [a] → [b] → [(a, b)]
zipLazy is a kind of zip that is lazy in the second list\n", - "(observe the ~)\n", + "genLNodes ∷ Enum a ⇒ a → Int → [LNode a](package fgl, module Data.Graph.Inductive.Example)
generate list of labeled nodes \n", "
\n", - "concurrently ∷ MonadBaseControl IO m ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\n", "
\n", - "concurrently ∷ ∀ m a b . (MonadBaseControl IO m, Forall (Pure m)) ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\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", - "pairADefault ∷ Applicative f ⇒ f a → f b → f (a, b)
Default '>*< implementation for non-invertible\n", - "Applicatives.\n", "
\n", - "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", + "threadList ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", + "threadList' ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", + "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "pair ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
Pair two samples. It's like zip but requires that both samples\n", - "have equal size.\n", "
\n", - "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", + "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", "
\n", - "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", - "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", + "mapAccumR ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "zip ∷ Sequence s ⇒ s a → s b → s (a, b)
Combine two sequences into a sequence of pairs. If the sequences are\n", - "different lengths, the excess elements of the longer sequence is\n", - "discarded.\n", - "\n", - "
\n",
-       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
-       "where j = min {n,m}\n",
-       "
\n", - "\n", - "Axioms:\n", - "\n", - "
    \n", - "
  • zip xs ys = zipWith (,) xs ys
  • \n", - "
\n", - "\n", - "This function is always unambiguous.\n", - "\n", - "Default running time: O( min( n1, n2 ) )\n", "
\n", - "zipUsingLview ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", - "zipUsingLists ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", - "concurrently ∷ MonadConc m ⇒ m a → m b → m (a, b)
Run two MonadConc actions concurrently, and return both\n", - "results. If either action throws an exception at any time, then the\n", - "other action is cancelled, and the exception is re-thrown by\n", - "concurrently.\n", - "\n", - "
\n",
-       "concurrently left right =\n",
-       "withAsync left $ \\a ->\n",
-       "withAsync right $ \\b ->\n",
-       "waitBoth a b\n",
-       "
\n", + "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "mzipRep ∷ Representable f ⇒ f a → f b → f (a, b)
\n", - "box ∷ Graph g ⇒ g a → g b → g (a, b)
Compute the Cartesian product of graphs. Complexity: O(s1 *\n", - "s2) time, memory and size, where s1 and s2 are the\n", - "sizes of the given graphs.\n", - "\n", - "
\n",
-       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
-       ", ((0,'a'), (1,'a'))\n",
-       ", ((0,'b'), (1,'b'))\n",
-       ", ((1,'a'), (1,'b')) ]\n",
-       "
\n", - "\n", - "Up to an isomorphism between the resulting vertex types, this\n", - "operation is commutative, associative,\n", - "distributes over overlay, has singleton graphs as\n", - "identities and empty as the annihilating zero.\n", - "Below ~~ stands for the equality up to an isomorphism, e.g.\n", - "(x, ()) ~~ x.\n", - "\n", - "
\n",
-       "box x y               ~~ box y x\n",
-       "box x (box y z)       ~~ box (box x y) z\n",
-       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
-       "box x (vertex ())     ~~ x\n",
-       "box x empty           ~~ empty\n",
-       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
-       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
-       "
\n", "
\n", - "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
-       "divided = divide id\n",
-       "
\n", + "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", "
\n", - "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
The RecordInputType divisible (contravariant) functor allows\n", - "you to build an InputType injector for a Dhall record.\n", - "\n", - "For example, let's take the following Haskell data type:\n", - "\n", - "
\n",
-       "data Project = Project\n",
-       "{ projectName :: Text\n",
-       ", projectDescription :: Text\n",
-       ", projectStars :: Natural\n",
-       "}\n",
-       "
\n", - "\n", - "And assume that we have the following Dhall record that we would like\n", - "to parse as a Project:\n", - "\n", - "
\n",
-       "{ name =\n",
-       "\"dhall-haskell\"\n",
-       ", description =\n",
-       "\"A configuration language guaranteed to terminate\"\n",
-       ", stars =\n",
-       "289\n",
-       "}\n",
-       "
\n", - "\n", - "Our injector has type InputType Project, but we can't\n", - "build that out of any smaller injectors, as InputTypes cannot\n", - "be combined (they are only Contravariants). However, we can use\n", - "an InputRecordType to build an InputType for\n", - "Project:\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputFieldWith \"name\" inject\n",
-       ">*< inputFieldWith \"description\" inject\n",
-       ">*< inputFieldWith \"stars\" inject\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Or, since we are simply using the Inject instance to inject\n", - "each field, we could write\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputField \"name\"\n",
-       ">*< inputField \"description\"\n",
-       ">*< inputField \"stars\"\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Infix divided\n", "
\n", - "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
-       "divided = divide id\n",
-       "
\n", + "mapAccumR ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", - "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", + "mapAccumL ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", "
\n", - "contrazip2 ∷ Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", - "contrazip2 ∷ ∀ f a1 a2 . Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", - "pair ∷ Sized f ⇒ f a → f b → f (a, b)
Default: pair a b = (,) $ a * b.\n", "
\n", - "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
A pairing/concatenation operator for builder primitives, both bounded\n", - "and fixed size.\n", - "\n", - "For example,\n", - "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
-       "
\n", - "\n", - "We can combine multiple primitives using >*< multiple\n", - "times.\n", - "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
-       "
\n", + "mapAccumR ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", "
\n", - "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
Merge two functors into a tuple, analogous to liftA2\n", - "(,). (Sometimes known as **.)\n", "
\n", - "zip ∷ List l ⇒ l a → l b → l (a, b)
\n", - "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", - "zip ∷ (Zip f) ⇒ f a → f b → f (a, b)
\n", - "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", - "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", - "mzip ∷ MonadZip m ⇒ m a → m b → m (a, b)
\n", - "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\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", - "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", "
\n", - "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "breakSubstring ∷ ByteString → ByteString → (ByteString, ByteString)(package bytestring, module Data.ByteString)
otherwise -> Just (length x) \n", "
\n", - "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "
For example, to tokenise a string, dropping delimiters:\n", "
\n", - "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "
> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", + "> \n", "
\n", - "biunfold ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Given a way to generate elements, return a way to generate structures\n", - "containing those elements.\n", + "
\n", + "
To skip to the first occurence of a string:\n", "
\n", - "biunfoldBF ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Breadth-first unfold, which orders the result by the number of\n", - "choose calls.\n", + "
\n", + "
> snd (breakSubstring x y)\n", "
\n", - "deserializeWith2 ∷ (Serial2 f, MonadGet m) ⇒ m a → m b → m (f a b)
\n", - "biunfoldRestrict ∷ (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) ⇒ f a → f b → f (t a b)
\n", - "biunfoldRestrictBF ∷ (BiunfoldableR p q t, Unfolder f, p a, q b) ⇒ f a → f b → f (t a b)
\n", - "mesh ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a mesh graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", - "\n", - "
\n",
-       "mesh xs     []   == empty\n",
-       "mesh []     ys   == empty\n",
-       "mesh [x]    [y]  == vertex (x, y)\n",
-       "mesh xs     ys   == box (path xs) (path ys)\n",
-       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
-       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
-       "
\n", + "
\n", + "
To take the parts of a string before a delimiter:\n", "
\n", - "torus ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a torus graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", - "\n", - "
\n",
-       "torus xs    []   == empty\n",
-       "torus []    ys   == empty\n",
-       "torus [x]   [y]  == edge (x,y) (x,y)\n",
-       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
-       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
-       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
-       "
\n", + "
\n", + "
> fst (breakSubstring x y) \n", "
\n", - "zipExactMay ∷ [a] → [b] → Maybe [(a, b)]
\n" + "
\n", + "breakOn ∷ Text → Text → (Text, Text)(package text, module Data.Text)
O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", + "
\n", + "
\n", + "
Examples:\n", + "
\n", + "
\n", + "
> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", + "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", + "
\n", + "
\n", + "
Laws:\n", + "
\n", + "
\n", + "
> append prefix match == haystack\n", + "> \n", + "
\n", + "
\n", + "
If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", + "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m). \n", + "
\n", + "
\n" ], "text/plain": [ "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/Data-List.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/GHC-List.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/GHC-OldList.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/hspec/docs/Test-Hspec-Discover.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zipExact :: Partial => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExact\n", - "
\n",
-       "zipExact xs ys =\n",
-       "| length xs == length ys = zip xs ys\n",
-       "| otherwise              = error \"some message\"\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base-compat/docs/Prelude-Compat.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude-Base.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-List.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/fay-base/docs/Prelude.html#v:zip\n", - "\n", - "(+*+) :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:-43--42--43-\n", - "Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", - "lists, produce a single list such that whenever v and\n", - "w have finite indices in the input lists, (v,w) has\n", - "finite index in the output list. Lower indices occur as the\n", - "fst part of the tuple more frequently, but not exponentially\n", - "so.\n", - "\n", - "unfairCartesianProduct :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:unfairCartesianProduct\n", - "Very unfair 2-way Cartesian product: same guarantee as the slightly\n", - "unfair one, except that lower indices may occur as the fst\n", - "part of the tuple exponentially more frequently. This mainly exists as\n", - "a specification to test against.\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/universum/docs/Universum-List-Reexport.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/prelude-compat/docs/Data-List2010.html#v:zip\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/prelude-compat/docs/Prelude2010.html#v:zip\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq-ListSeq.html#v:zip\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/intro/docs/Intro.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/relude/docs/Relude-List-Reexport.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zipLazy :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/ghc/docs/Util.html#v:zipLazy\n", - "zipLazy is a kind of zip that is lazy in the second list\n", - "(observe the ~)\n", - "\n", - "concurrently :: MonadBaseControl IO m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted.html#v:concurrently\n", - "Generalized version of concurrently.\n", - "\n", - "concurrently :: forall m a b . (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted-Safe.html#v:concurrently\n", - "Generalized version of concurrently.\n", - "\n", - "pairADefault :: Applicative f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:pairADefault\n", - "Default '>*< implementation for non-invertible\n", - "Applicatives.\n", - "\n", - "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:zip\n", - "O(min(m,n)) Zip two vectors\n", - "\n", - "pair :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", - "URL: https://hackage.haskell.org/package/statistics/docs/Statistics-Sample.html#v:pair\n", - "Pair two samples. It's like zip but requires that both samples\n", - "have equal size.\n", - "\n", - "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:zip\n", - "O(min(m,n)) Zip two vectors\n", - "\n", - "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/unliftio/docs/UnliftIO-Async.html#v:concurrently\n", - "Unlifted concurrently.\n", - "\n", - "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/yesod-websockets/docs/Yesod-WebSockets.html#v:concurrently\n", - "Unlifted concurrently.\n", - "\n", - "zip :: Sequence s => s a -> s b -> s (a, b)\n", - "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq.html#v:zip\n", - "Combine two sequences into a sequence of pairs. If the sequences are\n", - "different lengths, the excess elements of the longer sequence is\n", - "discarded.\n", - "\n", - "
\n",
-       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
-       "where j = min {n,m}\n",
-       "
\n", - "\n", - "Axioms:\n", - "\n", - "
    \n", - "
  • zip xs ys = zipWith (,) xs ys
  • \n", - "
\n", - "\n", - "This function is always unambiguous.\n", - "\n", - "Default running time: O( min( n1, n2 ) )\n", - "\n", - "zipUsingLview :: Sequence s => s a -> s b -> s (a, b)\n", - "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLview\n", - "\n", - "zipUsingLists :: Sequence s => s a -> s b -> s (a, b)\n", - "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLists\n", - "\n", - "concurrently :: MonadConc m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/concurrency/docs/Control-Concurrent-Classy-Async.html#v:concurrently\n", - "Run two MonadConc actions concurrently, and return both\n", - "results. If either action throws an exception at any time, then the\n", - "other action is cancelled, and the exception is re-thrown by\n", - "concurrently.\n", - "\n", - "
\n",
-       "concurrently left right =\n",
-       "withAsync left $ \\a ->\n",
-       "withAsync right $ \\b ->\n",
-       "waitBoth a b\n",
-       "
\n", - "\n", - "mzipRep :: Representable f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/adjunctions/docs/Data-Functor-Rep.html#v:mzipRep\n", - "\n", - "box :: Graph g => g a -> g b -> g (a, b)\n", - "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:box\n", - "Compute the Cartesian product of graphs. Complexity: O(s1 *\n", - "s2) time, memory and size, where s1 and s2 are the\n", - "sizes of the given graphs.\n", - "\n", - "
\n",
-       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
-       ", ((0,'a'), (1,'a'))\n",
-       ", ((0,'b'), (1,'b'))\n",
-       ", ((1,'a'), (1,'b')) ]\n",
-       "
\n", - "\n", - "Up to an isomorphism between the resulting vertex types, this\n", - "operation is commutative, associative,\n", - "distributes over overlay, has singleton graphs as\n", - "identities and empty as the annihilating zero.\n", - "Below ~~ stands for the equality up to an isomorphism, e.g.\n", - "(x, ()) ~~ x.\n", - "\n", - "
\n",
-       "box x y               ~~ box y x\n",
-       "box x (box y z)       ~~ box (box x y) z\n",
-       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
-       "box x (vertex ())     ~~ x\n",
-       "box x empty           ~~ empty\n",
-       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
-       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
-       "
\n", - "\n", - "divided :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/contravariant/docs/Data-Functor-Contravariant-Divisible.html#v:divided\n", - "
\n",
-       "divided = divide id\n",
-       "
\n", - "\n", - "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/dhall/docs/Dhall.html#v:-62--42--60-\n", - "The RecordInputType divisible (contravariant) functor allows\n", - "you to build an InputType injector for a Dhall record.\n", - "\n", - "For example, let's take the following Haskell data type:\n", - "\n", - "
\n",
-       "data Project = Project\n",
-       "{ projectName :: Text\n",
-       ", projectDescription :: Text\n",
-       ", projectStars :: Natural\n",
-       "}\n",
-       "
\n", - "\n", - "And assume that we have the following Dhall record that we would like\n", - "to parse as a Project:\n", - "\n", - "
\n",
-       "{ name =\n",
-       "\"dhall-haskell\"\n",
-       ", description =\n",
-       "\"A configuration language guaranteed to terminate\"\n",
-       ", stars =\n",
-       "289\n",
-       "}\n",
-       "
\n", - "\n", - "Our injector has type InputType Project, but we can't\n", - "build that out of any smaller injectors, as InputTypes cannot\n", - "be combined (they are only Contravariants). However, we can use\n", - "an InputRecordType to build an InputType for\n", - "Project:\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputFieldWith \"name\" inject\n",
-       ">*< inputFieldWith \"description\" inject\n",
-       ">*< inputFieldWith \"stars\" inject\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Or, since we are simply using the Inject instance to inject\n", - "each field, we could write\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputField \"name\"\n",
-       ">*< inputField \"description\"\n",
-       ">*< inputField \"stars\"\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Infix divided\n", - "\n", - "divided :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:divided\n", - "
\n",
-       "divided = divide id\n",
-       "
\n", - "\n", - "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:-62--42--60-\n", - "An alias to divided.\n", - "\n", - "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras.html#v:-62--42--60-\n", - "An alias to divided.\n", - "\n", - "contrazip2 :: Divisible f => f a1 -> f a2 -> f (a1, a2)\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:contrazip2\n", - "\n", - "contrazip2 :: forall f a1 a2 . Divisible f => f a1 -> f a2 -> f (a1, a2)\n", - "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras-Contrazip.html#v:contrazip2\n", - "\n", - "pair :: Sized f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/size-based/docs/Control-Sized.html#v:pair\n", - "Default: pair a b = (,) $ a * b.\n", - "\n", + "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:zip\n", + "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", "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/bytestring/docs/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", - "A pairing/concatenation operator for builder primitives, both bounded\n", - "and fixed size.\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", + "A pairing/concatenation operator for builder primitives, both bounded and fixed size.\n", "\n", "For example,\n", "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
-       "
\n", + "> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", "\n", - "We can combine multiple primitives using >*< multiple\n", - "times.\n", + "We can combine multiple primitives using >*< multiple times.\n", "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
-       "
\n", + "> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", + "shrinkState :: ShrinkState s a => a -> s -> [(a, s)]\n", + "URL: http://hackage.haskell.org/packages/archive/QuickCheck/latest/doc/html/Test-QuickCheck-Modifiers.html#v:shrinkState\n", "\n", - "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:-62--42--60-\n", - "Merge two functors into a tuple, analogous to liftA2\n", - "(,). (Sometimes known as **.)\n", + "breakOnAll :: Text -> Text -> [(Text, Text)]\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOnAll\n", + "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", "\n", - "zip :: List l => l a -> l b -> l (a, b)\n", - "URL: https://hackage.haskell.org/package/List/docs/Data-List-Class.html#v:zip\n", + "* The entire string prior to the kth match (i.e. the prefix)\n", + "* The kth match, followed by the remainder of the string\n", "\n", - "zip :: Zip f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/classy-prelude/docs/ClassyPrelude.html#v:zip\n", + "Examples:\n", "\n", - "zip :: (Zip f) => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/non-empty/docs/Data-NonEmpty-Class.html#v:zip\n", + "> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "\n", - "zip :: Zip f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/keys/docs/Data-Key.html#v:zip\n", + "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "\n", - "zip :: Zip f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/chunked-data/docs/Data-ChunkedZip.html#v:zip\n", + "The needle parameter may not be empty. \n", + "breakOnAll :: Text -> Text -> [(Text, Text)]\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text-Lazy.html#v:breakOnAll\n", + "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", "\n", - "mzip :: MonadZip m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/base/docs/Control-Monad-Zip.html#v:mzip\n", + "* The entire string prior to the kth match (i.e. the prefix)\n", + "* The kth match, followed by the remainder of the string\n", "\n", - "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:projectZip\n", - "Zipping projections.\n", + "Examples:\n", "\n", - "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:-62--60-\n", - "Binary operator the same as projectZip.\n", + "> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "\n", - "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:projectZip\n", - "Zipping projections.\n", + "This function is strict in its first argument, and lazy in its second.\n", "\n", - "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:-62--60-\n", - "Binary operator the same as projectZip.\n", + "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "\n", - "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-record/docs/Database-Relational-Documentation.html#v:-62--60-\n", - "Binary operator the same as projectZip.\n", + "The needle parameter may not be empty. \n", + "genLNodes :: Enum a => a -> Int -> [LNode a]\n", + "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Example.html#v:genLNodes\n", + "generate list of labeled nodes \n", + "gmapAccumT :: Data d => (forall e. Data e => a -> e -> (a, e)) -> a -> d -> (a, d)\n", + "URL: http://hackage.haskell.org/packages/archive/syb/latest/doc/html/Data-Generics-Twins.html#v:gmapAccumT\n", + "gmapT with accumulation \n", + "threadList :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", + "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList\n", "\n", - "biunfold :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfold\n", - "Given a way to generate elements, return a way to generate structures\n", - "containing those elements.\n", + "threadList' :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", + "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList-39-\n", "\n", - "biunfoldBF :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfoldBF\n", - "Breadth-first unfold, which orders the result by the number of\n", - "choose calls.\n", + "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "mapAccumR :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumR\n", + "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy-Char8.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "mapAccumR :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumR\n", + "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumL\n", + "O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", + "mapAccumR :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumR\n", + "The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", + "execRWS :: RWS r w s a -> r -> s -> (s, w)\n", + "URL: http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html#v:execRWS\n", + "Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n", + "breakSubstring :: ByteString -> ByteString -> (ByteString, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:breakSubstring\n", + "otherwise -> Just (length x) \n", "\n", - "deserializeWith2 :: (Serial2 f, MonadGet m) => m a -> m b -> m (f a b)\n", - "URL: https://hackage.haskell.org/package/bytes/docs/Data-Bytes-Serial.html#v:deserializeWith2\n", + "For example, to tokenise a string, dropping delimiters:\n", "\n", - "biunfoldRestrict :: (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrict\n", + "> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", + "> \n", "\n", - "biunfoldRestrictBF :: (BiunfoldableR p q t, Unfolder f, p a, q b) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrictBF\n", + "To skip to the first occurence of a string:\n", "\n", - "mesh :: Graph g => [a] -> [b] -> g (a, b)\n", - "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:mesh\n", - "Construct a mesh graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", + "> snd (breakSubstring x y)\n", "\n", - "
\n",
-       "mesh xs     []   == empty\n",
-       "mesh []     ys   == empty\n",
-       "mesh [x]    [y]  == vertex (x, y)\n",
-       "mesh xs     ys   == box (path xs) (path ys)\n",
-       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
-       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
-       "
\n", + "To take the parts of a string before a delimiter:\n", "\n", - "torus :: Graph g => [a] -> [b] -> g (a, b)\n", - "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:torus\n", - "Construct a torus graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", + "> fst (breakSubstring x y) \n", + "breakOn :: Text -> Text -> (Text, Text)\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOn\n", + "O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", "\n", - "
\n",
-       "torus xs    []   == empty\n",
-       "torus []    ys   == empty\n",
-       "torus [x]   [y]  == edge (x,y) (x,y)\n",
-       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
-       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
-       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
-       "
\n", + "Examples:\n", "\n", - "zipExactMay :: [a] -> [b] -> Maybe [(a, b)]\n", - "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExactMay" + "> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", + "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", + "\n", + "Laws:\n", + "\n", + "> append prefix match == haystack\n", + "> \n", + "\n", + "If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", + "\n", + "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m)." ] }, "metadata": {}, @@ -3308,7 +2236,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If you need a refresher on all of the options, you can just use `:help`:" ] @@ -3316,7 +2247,11 @@ { "cell_type": "code", "execution_count": 26, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3353,7 +2288,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "All of the code you normally put into IHaskell is (like in GHCi) interpreted. However, sometimes you've perfected a function, and now need it to run faster. In that case, you can go ahead and define a module in a single cell. As long as your module has a module header along the lines of `module Name where`, IHaskell will recognize it as a module. It will create the file `A/B.hs`, compile it, and load it. " ] @@ -3361,7 +2299,11 @@ { "cell_type": "code", "execution_count": 27, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- If your code isn't running fast enough, you can just put it into a module.\n", @@ -3374,7 +2316,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Note that the module is by default imported unqualified, as though you had typed `import A.B`." ] @@ -3382,7 +2327,11 @@ { "cell_type": "code", "execution_count": 28, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3411,7 +2360,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Note that since a new module is imported, all previous bound identifiers are now unbound. For instance, we no longer have access to the `f` function from before:" ] @@ -3419,7 +2371,11 @@ { "cell_type": "code", "execution_count": 29, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3521,7 +2477,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "However, if you re-import this module with another import statement, the original implicit import goes away." ] @@ -3529,7 +2488,11 @@ { "cell_type": "code", "execution_count": 30, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3559,7 +2522,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Thanks!\n", "---\n", @@ -3583,8 +2549,7 @@ "codemirror_mode": "ihaskell", "file_extension": ".hs", "name": "haskell", - "pygments_lexer": "Haskell", - "version": "8.4.3" + "version": "8.0.2" }, "latex_envs": { "bibliofile": "biblio.bib", @@ -3605,5 +2570,5 @@ } }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 0 } From 01366b6309be3e6ca4e934424fd02efbf7eb2215 Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Thu, 1 Nov 2018 21:53:50 +0100 Subject: [PATCH 08/10] Update demo notebook after changes to the hoogle search. --- notebooks/IHaskell.ipynb | 1886 ++++++++++++++++++++++++++++---------- 1 file changed, 1406 insertions(+), 480 deletions(-) diff --git a/notebooks/IHaskell.ipynb b/notebooks/IHaskell.ipynb index 2818d75f..80af54a9 100644 --- a/notebooks/IHaskell.ipynb +++ b/notebooks/IHaskell.ipynb @@ -2,10 +2,7 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "![](https://camo.githubusercontent.com/f6540337202bb3b0c2545d90de0791c9196f9510/68747470733a2f2f7261772e6769746875622e636f6d2f67696269616e736b792f494861736b656c6c2f6d61737465722f68746d6c2f6c6f676f2d36347836342e706e67)\n", "\n", @@ -21,11 +18,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -54,10 +47,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "As you can see, each input cell get an execution number. The first input cell is labeled `In [1]`. Just like in GHCi, the output of the last executed statement or expression is available via the `it` variable - however, in addition, the output of the $n$th cell is available via the `itN` variable. For example, if we wanted to see what the first cell printed, we can go ahead and output that:" ] @@ -65,11 +55,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -87,10 +73,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to simple code cells such as the ones you see, you can also have other types of cells. All of this inline text, for instance, is written using Markdown cells, which support the majority of Github markdown syntax. This lets you embed images and formatting and arbitrary HTML interspersed with your Haskell code. In addition, you can export these notebooks into HTML or even as presentations using `reveal.js`. \n", "\n", @@ -100,11 +83,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -127,10 +106,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to multi-line expressions, IHaskell supports most things that you could put in a standard Haskell file. For example, we can have function bindings without the `let` that GHCi requires. (As long as you group type signatures and their corresponding declarations together, you can use pattern matching and put signatures on your top-level declarations!)" ] @@ -138,11 +114,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -174,10 +146,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "So far we've just looked at pure functions, but nothing is stopping us from doing IO." ] @@ -185,11 +154,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -207,10 +172,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "IHaskell supports most GHC extensions via the `:extension` directive (or any shorthand thereof)." ] @@ -218,11 +180,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -329,11 +287,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- And enable extensions.\n", @@ -343,10 +297,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Data declarations do pretty much what you expect, and work fine on multiple lines. If a declaration turns out to be not quite what you wanted, you can just go back, edit it, and re-evaluate the code cell." ] @@ -354,11 +305,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -382,10 +329,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Although this doesn't hold everywhere, we've tried to keep IHaskell relatively similar to GHCi in terms of naming. So, just like in GHCi, you can inspect types with `:type` (or shorthands):" ] @@ -393,11 +337,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -500,10 +440,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The same goes for the `:info` command. However, unlike GHCi, which simply prints info, the IHaskell notebook brings up a separate pane." ] @@ -511,11 +448,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -530,10 +463,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane that pops up after this is evaluated. However, you can disable the interactive pager, and instead just show the output below the cell:" ] @@ -541,11 +471,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- Only takes effect on later cells, so stick it in its own cell.\n", @@ -555,11 +481,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -691,10 +613,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "We can now write slightly more complicated scripts." ] @@ -702,11 +621,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -734,10 +649,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "This is where the similarities with GHCi end, and the particularly shiny features of IHaskell begin.\n", "\n", @@ -747,11 +659,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "data Color = Red | Green | Blue" @@ -759,10 +667,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If we were playing around with designing GUI applications, for instance, we might want to actually *see* these colors, instead of just seeing the text \"Red\", \"Green\", and \"Blue\" when we are debugging.\n", "\n", @@ -772,11 +677,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import IHaskell.Display\n", @@ -794,10 +695,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Once we define a custom `display :: a -> IO Display` function, we can simply output a `Color`:" ] @@ -805,11 +703,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1090,10 +984,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `DisplayData` type has several constructors which let you display your data as plain text, HTML, images (SVG, PNG, JPG), or even as LaTeX code.\n", "\n", @@ -1104,10 +995,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-aeson` package adds a display for [Aeson](http://hackage.haskell.org/package/aeson) JSON `Value` types. These are automatically formatted as JSON, rather than as Haskell values:" ] @@ -1115,16 +1003,12 @@ { "cell_type": "code", "execution_count": 17, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "null" + "Null" ] }, "metadata": {}, @@ -1133,7 +1017,7 @@ { "data": { "text/plain": [ - "true" + "Bool True" ] }, "metadata": {}, @@ -1142,10 +1026,7 @@ { "data": { "text/plain": [ - "{\n", - " \"x\": 3,\n", - " \"y\": 2\n", - "}" + "Object (fromList [(\"x\",Number 3.0),(\"y\",Number 2.0)])" ] }, "metadata": {}, @@ -1169,10 +1050,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-blaze` package lets you play around with HTML straight from within IHaskell using the [Blaze](http://jaspervdj.be/blaze/tutorial.html) library." ] @@ -1180,11 +1058,7 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1413,10 +1287,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-diagrams` package allows you to experiment with the [diagrams](http://projects.haskell.org/diagrams/) package. It requires the Cairo backend." ] @@ -1424,15 +1295,11 @@ { "cell_type": "code", "execution_count": 19, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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" + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1461,10 +1328,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Just like with Diagrams, `ihaskell-charts` allows you to use the [Chart](https://github.com/timbod7/haskell-chart/wiki) library for plotting from within IHaskell. (You will need to install `cairo` as well, which may be a bit of a hassle.)" ] @@ -1472,15 +1336,11 @@ { "cell_type": "code", "execution_count": 20, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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" + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1514,10 +1374,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to displaying outputs in a rich format, IHaskell has a bunch of useful features.\n", "\n", @@ -1527,11 +1384,7 @@ { "cell_type": "code", "execution_count": 21, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1668,10 +1521,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you're an experienced Haskeller, though, and don't want `hlint` telling you what to do, you can easily turn it off:" ] @@ -1679,11 +1529,7 @@ { "cell_type": "code", "execution_count": 22, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- If hlint annoys you, though, you can turn it off.\n", @@ -1694,11 +1540,7 @@ { "cell_type": "code", "execution_count": 23, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1717,10 +1559,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to `hlint` integration, IHaskell also integrates **Hoogle** for documentation searches. IHaskell provides two directives for searching Hoogle. The first of these, `:document` (or shorthands), looks for exact matches." ] @@ -1728,11 +1567,7 @@ { "cell_type": "code", "execution_count": 24, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -1823,14 +1658,243 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a](package base, module Control.Monad)
This generalizes the list-based filter function. \n", + "filterM ∷ Applicative m ⇒ (a → m Bool) → [a] → m [a]
This generalizes the list-based filter function.\n", "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle v a → Bundle m v a
Yield a monadic stream of elements that satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle m v a → Bundle m v a
Drop elements which do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Stream m a → Stream m a
Drop elements which do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Vector v a) ⇒ (a → m Bool) → v a → m (v a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Prim a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Storable a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Unbox a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → ConduitT a a m ()
Keep only values in the stream passing a given monadic predicate.\n", + "\n", + "Subject to fusion\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Pipe a a m r
(filterM predicate) only forwards values that satisfy the\n", + "monadic predicate\n", + "\n", + "
\n",
+       "filterM (pure (pure True)) = cat\n",
+       "\n",
+       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
+       "
\n", + "
\n", + "filterM ∷ (a → IO Bool) → InputStream a → IO (InputStream a)
Drops chunks from an input stream if they fail to match a given filter\n", + "predicate. See filter.\n", + "\n", + "Items pushed back to the returned stream are propagated back upstream.\n", + "\n", + "Example:\n", + "\n", + "
\n",
+       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
+       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
+       "[\"the\",\"quick\",\"fox\"]\n",
+       "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ (IsSequence seq, Monad m) ⇒ (Element seq → m Bool) → seq → m seq
The monadic version of filter.\n", + "
\n", + "filterM ∷ (Monad m) ⇒ (a → m Bool) → Stream (Of a) m r → Stream (Of a) m r
Skip elements of a stream that fail a monadic test\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ (Monad m, Vector v a) ⇒ a → m Bool → v a → m v a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Storable a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Unbox a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a]
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ (Applicative f) ⇒ (a → f Bool) → [a] → f [a]
See mapM.\n", + "
\n", + "filterM ∷ (Monad m, Vector u a, Vector v b) ⇒ ((a, b) → m Bool) → Vector u v (a, b) → m (Vector u v (a, b))
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (IsStream t, Monad m) ⇒ (a → m Bool) → t m a → t m a
Same as filter but with a monadic predicate.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", "
\n" ], "text/plain": [ + "filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Bundle v a -> Bundle m v a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle.html#v:filterM\n", + "Yield a monadic stream of elements that satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Bundle m v a -> Bundle m v a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle-Monadic.html#v:filterM\n", + "Drop elements which do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Stream-Monadic.html#v:filterM\n", + "Drop elements which do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Vector v a) => (a -> m Bool) -> v a -> m (v a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Prim a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Primitive.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Storable a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Storable.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Unbox a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> ConduitT a a m ()\n", + "URL: https://hackage.haskell.org/package/conduit/docs/Data-Conduit-Combinators.html#v:filterM\n", + "Keep only values in the stream passing a given monadic predicate.\n", + "\n", + "Subject to fusion\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Pipe a a m r\n", + "URL: https://hackage.haskell.org/package/pipes/docs/Pipes-Prelude.html#v:filterM\n", + "(filterM predicate) only forwards values that satisfy the\n", + "monadic predicate\n", + "\n", + "
\n",
+       "filterM (pure (pure True)) = cat\n",
+       "\n",
+       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
+       "
\n", + "\n", + "filterM :: (a -> IO Bool) -> InputStream a -> IO (InputStream a)\n", + "URL: https://hackage.haskell.org/package/io-streams/docs/System-IO-Streams-Combinators.html#v:filterM\n", + "Drops chunks from an input stream if they fail to match a given filter\n", + "predicate. See filter.\n", + "\n", + "Items pushed back to the returned stream are propagated back upstream.\n", + "\n", + "Example:\n", + "\n", + "
\n",
+       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
+       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
+       "[\"the\",\"quick\",\"fox\"]\n",
+       "
\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude-Monad.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (IsSequence seq, Monad m) => (Element seq -> m Bool) -> seq -> m seq\n", + "URL: https://hackage.haskell.org/package/mono-traversable/docs/Data-Sequences.html#v:filterM\n", + "The monadic version of filter.\n", + "\n", + "filterM :: (Monad m) => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m r\n", + "URL: https://hackage.haskell.org/package/streaming/docs/Streaming-Prelude.html#v:filterM\n", + "Skip elements of a stream that fail a monadic test\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (Monad m, Vector v a) => a -> m Bool -> v a -> m v a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Boxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Storable a) => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Storable.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Unbox a) => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Unboxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", "filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]\n", - "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:filterM\n", - "This generalizes the list-based filter function." + "URL: https://hackage.haskell.org/package/yjtools/docs/Control-Monad-Tools.html#v:filterM\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/universum/docs/Universum-Monad-Reexport.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (Applicative f) => (a -> f Bool) -> [a] -> f [a]\n", + "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:filterM\n", + "See mapM.\n", + "\n", + "filterM :: (Monad m, Vector u a, Vector v b) => ((a, b) -> m Bool) -> Vector u v (a, b) -> m (Vector u v (a, b))\n", + "URL: https://hackage.haskell.org/package/hybrid-vectors/docs/Data-Vector-Hybrid.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a\n", + "URL: https://hackage.haskell.org/package/streamly/docs/Streamly-Prelude.html#v:filterM\n", + "Same as filter but with a monadic predicate.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/control-monad-free/docs/Control-Monad-Free.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/relude/docs/Relude-Monad-Reexport.html#v:filterM\n", + "This generalizes the list-based filter function." ] }, "metadata": {}, @@ -1843,10 +1907,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature. This will show you documentation for things that match the desired type signature, as demonstrated below. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations." ] @@ -1854,11 +1915,7 @@ { "cell_type": "code", "execution_count": 25, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -1949,281 +2006,1187 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "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", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\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", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", - "
\n", - "
For example,\n", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", - "
\n", - "
> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
We can combine multiple primitives using >*< multiple times.\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", + "zipExact ∷ Partial ⇒ [a] → [b] → [(a, b)]
\n",
+       "zipExact xs ys =\n",
+       "| length xs == length ys = zip xs ys\n",
+       "| otherwise              = error \"some message\"\n",
+       "
\n", "
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "shrinkState ∷ ShrinkState s a ⇒ a → s → [(a, s)](package QuickCheck, module Test.QuickCheck.Modifiers)
\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", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
* The entire string prior to the kth match (i.e. the prefix)\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
* The kth match, followed by the remainder of the string\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
Examples:\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
The needle parameter may not be empty. \n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "(+*+) ∷ [a] → [b] → [(a, b)]
Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", + "lists, produce a single list such that whenever v and\n", + "w have finite indices in the input lists, (v,w) has\n", + "finite index in the output list. Lower indices occur as the\n", + "fst part of the tuple more frequently, but not exponentially\n", + "so.\n", "
\n", + "unfairCartesianProduct ∷ [a] → [b] → [(a, b)]
Very unfair 2-way Cartesian product: same guarantee as the slightly\n", + "unfair one, except that lower indices may occur as the fst\n", + "part of the tuple exponentially more frequently. This mainly exists as\n", + "a specification to test against.\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", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
* The entire string prior to the kth match (i.e. the prefix)\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
* The kth match, followed by the remainder of the string\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
Examples:\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
This function is strict in its first argument, and lazy in its second.\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
The needle parameter may not be empty. \n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "genLNodes ∷ Enum a ⇒ a → Int → [LNode a](package fgl, module Data.Graph.Inductive.Example)
generate list of labeled nodes \n", + "zipLazy ∷ [a] → [b] → [(a, b)]
zipLazy is a kind of zip that is lazy in the second list\n", + "(observe the ~)\n", "
\n", + "concurrently ∷ MonadBaseControl IO m ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\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", + "concurrently ∷ ∀ m a b . (MonadBaseControl IO m, Forall (Pure m)) ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\n", "
\n", + "pairADefault ∷ Applicative f ⇒ f a → f b → f (a, b)
Default '>*< implementation for non-invertible\n", + "Applicatives.\n", "
\n", - "threadList ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", - "threadList' ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", - "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", "
\n", + "pair ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
Pair two samples. It's like zip but requires that both samples\n", + "have equal size.\n", "
\n", - "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", "
\n", + "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", - "mapAccumR ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", + "zip ∷ Sequence s ⇒ s a → s b → s (a, b)
Combine two sequences into a sequence of pairs. If the sequences are\n", + "different lengths, the excess elements of the longer sequence is\n", + "discarded.\n", + "\n", + "
\n",
+       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
+       "where j = min {n,m}\n",
+       "
\n", + "\n", + "Axioms:\n", + "\n", + "
    \n", + "
  • zip xs ys = zipWith (,) xs ys
  • \n", + "
\n", + "\n", + "This function is always unambiguous.\n", + "\n", + "Default running time: O( min( n1, n2 ) )\n", "
\n", - "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "zipUsingLview ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", + "zipUsingLists ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", + "concurrently ∷ MonadConc m ⇒ m a → m b → m (a, b)
Run two MonadConc actions concurrently, and return both\n", + "results. If either action throws an exception at any time, then the\n", + "other action is cancelled, and the exception is re-thrown by\n", + "concurrently.\n", + "\n", + "
\n",
+       "concurrently left right =\n",
+       "withAsync left $ \\a ->\n",
+       "withAsync right $ \\b ->\n",
+       "waitBoth a b\n",
+       "
\n", "
\n", + "mzipRep ∷ Representable f ⇒ f a → f b → f (a, b)
\n", + "box ∷ Graph g ⇒ g a → g b → g (a, b)
Compute the Cartesian product of graphs. Complexity: O(s1 *\n", + "s2) time, memory and size, where s1 and s2 are the\n", + "sizes of the given graphs.\n", + "\n", + "
\n",
+       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
+       ", ((0,'a'), (1,'a'))\n",
+       ", ((0,'b'), (1,'b'))\n",
+       ", ((1,'a'), (1,'b')) ]\n",
+       "
\n", + "\n", + "Up to an isomorphism between the resulting vertex types, this\n", + "operation is commutative, associative,\n", + "distributes over overlay, has singleton graphs as\n", + "identities and empty as the annihilating zero.\n", + "Below ~~ stands for the equality up to an isomorphism, e.g.\n", + "(x, ()) ~~ x.\n", + "\n", + "
\n",
+       "box x y               ~~ box y x\n",
+       "box x (box y z)       ~~ box (box x y) z\n",
+       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
+       "box x (vertex ())     ~~ x\n",
+       "box x empty           ~~ empty\n",
+       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
+       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
+       "
\n", "
\n", - "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
+       "divided = divide id\n",
+       "
\n", "
\n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
The RecordInputType divisible (contravariant) functor allows\n", + "you to build an InputType injector for a Dhall record.\n", + "\n", + "For example, let's take the following Haskell data type:\n", + "\n", + "
\n",
+       "data Project = Project\n",
+       "{ projectName :: Text\n",
+       ", projectDescription :: Text\n",
+       ", projectStars :: Natural\n",
+       "}\n",
+       "
\n", + "\n", + "And assume that we have the following Dhall record that we would like\n", + "to parse as a Project:\n", + "\n", + "
\n",
+       "{ name =\n",
+       "\"dhall-haskell\"\n",
+       ", description =\n",
+       "\"A configuration language guaranteed to terminate\"\n",
+       ", stars =\n",
+       "289\n",
+       "}\n",
+       "
\n", + "\n", + "Our injector has type InputType Project, but we can't\n", + "build that out of any smaller injectors, as InputTypes cannot\n", + "be combined (they are only Contravariants). However, we can use\n", + "an InputRecordType to build an InputType for\n", + "Project:\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputFieldWith \"name\" inject\n",
+       ">*< inputFieldWith \"description\" inject\n",
+       ">*< inputFieldWith \"stars\" inject\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Or, since we are simply using the Inject instance to inject\n", + "each field, we could write\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputField \"name\"\n",
+       ">*< inputField \"description\"\n",
+       ">*< inputField \"stars\"\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Infix divided\n", "
\n", - "mapAccumR ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
+       "divided = divide id\n",
+       "
\n", "
\n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", - "mapAccumL ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", + "contrazip2 ∷ Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", + "contrazip2 ∷ ∀ f a1 a2 . Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", + "pair ∷ Sized f ⇒ f a → f b → f (a, b)
Default: pair a b = (,) $ a * b.\n", "
\n", - "mapAccumR ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", - "
\n", - "
\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", - "breakSubstring ∷ ByteString → ByteString → (ByteString, ByteString)(package bytestring, module Data.ByteString)
otherwise -> Just (length x) \n", - "
\n", - "
\n", - "
For example, to tokenise a string, dropping delimiters:\n", - "
\n", - "
\n", - "
> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", - "> \n", - "
\n", - "
\n", - "
To skip to the first occurence of a string:\n", - "
\n", - "
\n", - "
> snd (breakSubstring x y)\n", - "
\n", - "
\n", - "
To take the parts of a string before a delimiter:\n", - "
\n", - "
\n", - "
> fst (breakSubstring x y) \n", - "
\n", - "
\n", - "breakOn ∷ Text → Text → (Text, Text)(package text, module Data.Text)
O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", - "
\n", - "
\n", - "
Examples:\n", - "
\n", - "
\n", - "
> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", - "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", - "
\n", - "
\n", - "
Laws:\n", - "
\n", - "
\n", - "
> append prefix match == haystack\n", - "> \n", - "
\n", - "
\n", - "
If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", - "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m). \n", - "
\n", - "
\n" - ], - "text/plain": [ - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:zip\n", - "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", - "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", - "A pairing/concatenation operator for builder primitives, both bounded and fixed size.\n", + "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
A pairing/concatenation operator for builder primitives, both bounded\n", + "and fixed size.\n", "\n", "For example,\n", "\n", - "> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
+       "
\n", "\n", - "We can combine multiple primitives using >*< multiple times.\n", + "We can combine multiple primitives using >*< multiple\n", + "times.\n", "\n", - "> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", - "shrinkState :: ShrinkState s a => a -> s -> [(a, s)]\n", - "URL: http://hackage.haskell.org/packages/archive/QuickCheck/latest/doc/html/Test-QuickCheck-Modifiers.html#v:shrinkState\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
+       "
\n", + "
\n", + "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
Merge two functors into a tuple, analogous to liftA2\n", + "(,). (Sometimes known as **.)\n", + "
\n", + "zip ∷ List l ⇒ l a → l b → l (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "zip ∷ (Zip f) ⇒ f a → f b → f (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "mzip ∷ MonadZip m ⇒ m a → m b → m (a, b)
\n", + "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "biunfold ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Given a way to generate elements, return a way to generate structures\n", + "containing those elements.\n", + "
\n", + "biunfoldBF ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Breadth-first unfold, which orders the result by the number of\n", + "choose calls.\n", + "
\n", + "deserializeWith2 ∷ (Serial2 f, MonadGet m) ⇒ m a → m b → m (f a b)
\n", + "biunfoldRestrict ∷ (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) ⇒ f a → f b → f (t a b)
\n", + "biunfoldRestrictBF ∷ (BiunfoldableR p q t, Unfolder f, p a, q b) ⇒ f a → f b → f (t a b)
\n", + "mesh ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a mesh graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", "\n", - "breakOnAll :: Text -> Text -> [(Text, Text)]\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOnAll\n", - "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "
\n",
+       "mesh xs     []   == empty\n",
+       "mesh []     ys   == empty\n",
+       "mesh [x]    [y]  == vertex (x, y)\n",
+       "mesh xs     ys   == box (path xs) (path ys)\n",
+       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
+       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
+       "
\n", + "
\n", + "torus ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a torus graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", "\n", - "* The entire string prior to the kth match (i.e. the prefix)\n", - "* The kth match, followed by the remainder of the string\n", + "
\n",
+       "torus xs    []   == empty\n",
+       "torus []    ys   == empty\n",
+       "torus [x]   [y]  == edge (x,y) (x,y)\n",
+       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
+       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
+       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
+       "
\n", + "
\n", + "zipExactMay ∷ [a] → [b] → Maybe [(a, b)]
\n" + ], + "text/plain": [ + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "Examples:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "The needle parameter may not be empty. \n", - "breakOnAll :: Text -> Text -> [(Text, Text)]\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text-Lazy.html#v:breakOnAll\n", - "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "zip is right-lazy:\n", "\n", - "* The entire string prior to the kth match (i.e. the prefix)\n", - "* The kth match, followed by the remainder of the string\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "Examples:\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/Data-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "This function is strict in its first argument, and lazy in its second.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "The needle parameter may not be empty. \n", - "genLNodes :: Enum a => a -> Int -> [LNode a]\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Example.html#v:genLNodes\n", - "generate list of labeled nodes \n", - "gmapAccumT :: Data d => (forall e. Data e => a -> e -> (a, e)) -> a -> d -> (a, d)\n", - "URL: http://hackage.haskell.org/packages/archive/syb/latest/doc/html/Data-Generics-Twins.html#v:gmapAccumT\n", - "gmapT with accumulation \n", - "threadList :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList\n", + "zip is right-lazy:\n", "\n", - "threadList' :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList-39-\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", - "mapAccumR :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy-Char8.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", - "mapAccumR :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumL\n", - "O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", - "mapAccumR :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", - "execRWS :: RWS r w s a -> r -> s -> (s, w)\n", - "URL: http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html#v:execRWS\n", - "Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n", - "breakSubstring :: ByteString -> ByteString -> (ByteString, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:breakSubstring\n", - "otherwise -> Just (length x) \n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/GHC-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "For example, to tokenise a string, dropping delimiters:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", - "> \n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "To skip to the first occurence of a string:\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "> snd (breakSubstring x y)\n", + "zip is right-lazy:\n", "\n", - "To take the parts of a string before a delimiter:\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "> fst (breakSubstring x y) \n", - "breakOn :: Text -> Text -> (Text, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOn\n", - "O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/GHC-OldList.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "Examples:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", - "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "Laws:\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "> append prefix match == haystack\n", - "> \n", + "zip is right-lazy:\n", "\n", - "If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m)." + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/hspec/docs/Test-Hspec-Discover.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zipExact :: Partial => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExact\n", + "
\n",
+       "zipExact xs ys =\n",
+       "| length xs == length ys = zip xs ys\n",
+       "| otherwise              = error \"some message\"\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base-compat/docs/Prelude-Compat.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude-Base.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/fay-base/docs/Prelude.html#v:zip\n", + "\n", + "(+*+) :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:-43--42--43-\n", + "Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", + "lists, produce a single list such that whenever v and\n", + "w have finite indices in the input lists, (v,w) has\n", + "finite index in the output list. Lower indices occur as the\n", + "fst part of the tuple more frequently, but not exponentially\n", + "so.\n", + "\n", + "unfairCartesianProduct :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:unfairCartesianProduct\n", + "Very unfair 2-way Cartesian product: same guarantee as the slightly\n", + "unfair one, except that lower indices may occur as the fst\n", + "part of the tuple exponentially more frequently. This mainly exists as\n", + "a specification to test against.\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universum/docs/Universum-List-Reexport.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/prelude-compat/docs/Data-List2010.html#v:zip\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/prelude-compat/docs/Prelude2010.html#v:zip\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq-ListSeq.html#v:zip\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/intro/docs/Intro.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/relude/docs/Relude-List-Reexport.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zipLazy :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/ghc/docs/Util.html#v:zipLazy\n", + "zipLazy is a kind of zip that is lazy in the second list\n", + "(observe the ~)\n", + "\n", + "concurrently :: MonadBaseControl IO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted.html#v:concurrently\n", + "Generalized version of concurrently.\n", + "\n", + "concurrently :: forall m a b . (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted-Safe.html#v:concurrently\n", + "Generalized version of concurrently.\n", + "\n", + "pairADefault :: Applicative f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:pairADefault\n", + "Default '>*< implementation for non-invertible\n", + "Applicatives.\n", + "\n", + "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:zip\n", + "O(min(m,n)) Zip two vectors\n", + "\n", + "pair :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/statistics/docs/Statistics-Sample.html#v:pair\n", + "Pair two samples. It's like zip but requires that both samples\n", + "have equal size.\n", + "\n", + "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:zip\n", + "O(min(m,n)) Zip two vectors\n", + "\n", + "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/unliftio/docs/UnliftIO-Async.html#v:concurrently\n", + "Unlifted concurrently.\n", + "\n", + "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/yesod-websockets/docs/Yesod-WebSockets.html#v:concurrently\n", + "Unlifted concurrently.\n", + "\n", + "zip :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq.html#v:zip\n", + "Combine two sequences into a sequence of pairs. If the sequences are\n", + "different lengths, the excess elements of the longer sequence is\n", + "discarded.\n", + "\n", + "
\n",
+       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
+       "where j = min {n,m}\n",
+       "
\n", + "\n", + "Axioms:\n", + "\n", + "
    \n", + "
  • zip xs ys = zipWith (,) xs ys
  • \n", + "
\n", + "\n", + "This function is always unambiguous.\n", + "\n", + "Default running time: O( min( n1, n2 ) )\n", + "\n", + "zipUsingLview :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLview\n", + "\n", + "zipUsingLists :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLists\n", + "\n", + "concurrently :: MonadConc m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/concurrency/docs/Control-Concurrent-Classy-Async.html#v:concurrently\n", + "Run two MonadConc actions concurrently, and return both\n", + "results. If either action throws an exception at any time, then the\n", + "other action is cancelled, and the exception is re-thrown by\n", + "concurrently.\n", + "\n", + "
\n",
+       "concurrently left right =\n",
+       "withAsync left $ \\a ->\n",
+       "withAsync right $ \\b ->\n",
+       "waitBoth a b\n",
+       "
\n", + "\n", + "mzipRep :: Representable f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/adjunctions/docs/Data-Functor-Rep.html#v:mzipRep\n", + "\n", + "box :: Graph g => g a -> g b -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:box\n", + "Compute the Cartesian product of graphs. Complexity: O(s1 *\n", + "s2) time, memory and size, where s1 and s2 are the\n", + "sizes of the given graphs.\n", + "\n", + "
\n",
+       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
+       ", ((0,'a'), (1,'a'))\n",
+       ", ((0,'b'), (1,'b'))\n",
+       ", ((1,'a'), (1,'b')) ]\n",
+       "
\n", + "\n", + "Up to an isomorphism between the resulting vertex types, this\n", + "operation is commutative, associative,\n", + "distributes over overlay, has singleton graphs as\n", + "identities and empty as the annihilating zero.\n", + "Below ~~ stands for the equality up to an isomorphism, e.g.\n", + "(x, ()) ~~ x.\n", + "\n", + "
\n",
+       "box x y               ~~ box y x\n",
+       "box x (box y z)       ~~ box (box x y) z\n",
+       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
+       "box x (vertex ())     ~~ x\n",
+       "box x empty           ~~ empty\n",
+       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
+       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
+       "
\n", + "\n", + "divided :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/contravariant/docs/Data-Functor-Contravariant-Divisible.html#v:divided\n", + "
\n",
+       "divided = divide id\n",
+       "
\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/dhall/docs/Dhall.html#v:-62--42--60-\n", + "The RecordInputType divisible (contravariant) functor allows\n", + "you to build an InputType injector for a Dhall record.\n", + "\n", + "For example, let's take the following Haskell data type:\n", + "\n", + "
\n",
+       "data Project = Project\n",
+       "{ projectName :: Text\n",
+       ", projectDescription :: Text\n",
+       ", projectStars :: Natural\n",
+       "}\n",
+       "
\n", + "\n", + "And assume that we have the following Dhall record that we would like\n", + "to parse as a Project:\n", + "\n", + "
\n",
+       "{ name =\n",
+       "\"dhall-haskell\"\n",
+       ", description =\n",
+       "\"A configuration language guaranteed to terminate\"\n",
+       ", stars =\n",
+       "289\n",
+       "}\n",
+       "
\n", + "\n", + "Our injector has type InputType Project, but we can't\n", + "build that out of any smaller injectors, as InputTypes cannot\n", + "be combined (they are only Contravariants). However, we can use\n", + "an InputRecordType to build an InputType for\n", + "Project:\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputFieldWith \"name\" inject\n",
+       ">*< inputFieldWith \"description\" inject\n",
+       ">*< inputFieldWith \"stars\" inject\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Or, since we are simply using the Inject instance to inject\n", + "each field, we could write\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputField \"name\"\n",
+       ">*< inputField \"description\"\n",
+       ">*< inputField \"stars\"\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Infix divided\n", + "\n", + "divided :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:divided\n", + "
\n",
+       "divided = divide id\n",
+       "
\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:-62--42--60-\n", + "An alias to divided.\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras.html#v:-62--42--60-\n", + "An alias to divided.\n", + "\n", + "contrazip2 :: Divisible f => f a1 -> f a2 -> f (a1, a2)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:contrazip2\n", + "\n", + "contrazip2 :: forall f a1 a2 . Divisible f => f a1 -> f a2 -> f (a1, a2)\n", + "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras-Contrazip.html#v:contrazip2\n", + "\n", + "pair :: Sized f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/size-based/docs/Control-Sized.html#v:pair\n", + "Default: pair a b = (,) $ a * b.\n", + "\n", + "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/bytestring/docs/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", + "A pairing/concatenation operator for builder primitives, both bounded\n", + "and fixed size.\n", + "\n", + "For example,\n", + "\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
+       "
\n", + "\n", + "We can combine multiple primitives using >*< multiple\n", + "times.\n", + "\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
+       "
\n", + "\n", + "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:-62--42--60-\n", + "Merge two functors into a tuple, analogous to liftA2\n", + "(,). (Sometimes known as **.)\n", + "\n", + "zip :: List l => l a -> l b -> l (a, b)\n", + "URL: https://hackage.haskell.org/package/List/docs/Data-List-Class.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/classy-prelude/docs/ClassyPrelude.html#v:zip\n", + "\n", + "zip :: (Zip f) => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/non-empty/docs/Data-NonEmpty-Class.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/keys/docs/Data-Key.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/chunked-data/docs/Data-ChunkedZip.html#v:zip\n", + "\n", + "mzip :: MonadZip m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/base/docs/Control-Monad-Zip.html#v:mzip\n", + "\n", + "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:projectZip\n", + "Zipping projections.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:projectZip\n", + "Zipping projections.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-record/docs/Database-Relational-Documentation.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "biunfold :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfold\n", + "Given a way to generate elements, return a way to generate structures\n", + "containing those elements.\n", + "\n", + "biunfoldBF :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfoldBF\n", + "Breadth-first unfold, which orders the result by the number of\n", + "choose calls.\n", + "\n", + "deserializeWith2 :: (Serial2 f, MonadGet m) => m a -> m b -> m (f a b)\n", + "URL: https://hackage.haskell.org/package/bytes/docs/Data-Bytes-Serial.html#v:deserializeWith2\n", + "\n", + "biunfoldRestrict :: (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrict\n", + "\n", + "biunfoldRestrictBF :: (BiunfoldableR p q t, Unfolder f, p a, q b) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrictBF\n", + "\n", + "mesh :: Graph g => [a] -> [b] -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:mesh\n", + "Construct a mesh graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", + "\n", + "
\n",
+       "mesh xs     []   == empty\n",
+       "mesh []     ys   == empty\n",
+       "mesh [x]    [y]  == vertex (x, y)\n",
+       "mesh xs     ys   == box (path xs) (path ys)\n",
+       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
+       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
+       "
\n", + "\n", + "torus :: Graph g => [a] -> [b] -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:torus\n", + "Construct a torus graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", + "\n", + "
\n",
+       "torus xs    []   == empty\n",
+       "torus []    ys   == empty\n",
+       "torus [x]   [y]  == edge (x,y) (x,y)\n",
+       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
+       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
+       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
+       "
\n", + "\n", + "zipExactMay :: [a] -> [b] -> Maybe [(a, b)]\n", + "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExactMay" ] }, "metadata": {}, @@ -2236,10 +3199,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you need a refresher on all of the options, you can just use `:help`:" ] @@ -2247,11 +3207,7 @@ { "cell_type": "code", "execution_count": 26, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2288,10 +3244,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "All of the code you normally put into IHaskell is (like in GHCi) interpreted. However, sometimes you've perfected a function, and now need it to run faster. In that case, you can go ahead and define a module in a single cell. As long as your module has a module header along the lines of `module Name where`, IHaskell will recognize it as a module. It will create the file `A/B.hs`, compile it, and load it. " ] @@ -2299,11 +3252,7 @@ { "cell_type": "code", "execution_count": 27, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- If your code isn't running fast enough, you can just put it into a module.\n", @@ -2316,10 +3265,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Note that the module is by default imported unqualified, as though you had typed `import A.B`." ] @@ -2327,11 +3273,7 @@ { "cell_type": "code", "execution_count": 28, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2360,10 +3302,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Note that since a new module is imported, all previous bound identifiers are now unbound. For instance, we no longer have access to the `f` function from before:" ] @@ -2371,11 +3310,7 @@ { "cell_type": "code", "execution_count": 29, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2477,10 +3412,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "However, if you re-import this module with another import statement, the original implicit import goes away." ] @@ -2488,11 +3420,7 @@ { "cell_type": "code", "execution_count": 30, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2522,10 +3450,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Thanks!\n", "---\n", @@ -2549,7 +3474,8 @@ "codemirror_mode": "ihaskell", "file_extension": ".hs", "name": "haskell", - "version": "8.0.2" + "pygments_lexer": "Haskell", + "version": "8.4.3" }, "latex_envs": { "bibliofile": "biblio.bib", @@ -2570,5 +3496,5 @@ } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From 105d0db474aab03c905fe903d21e97622e4f598d Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Fri, 2 Nov 2018 14:32:32 +0100 Subject: [PATCH 09/10] Revert "Update demo notebook after changes to the hoogle search." This reverts commit 01366b6309be3e6ca4e934424fd02efbf7eb2215. --- notebooks/IHaskell.ipynb | 1864 ++++++++++---------------------------- 1 file changed, 469 insertions(+), 1395 deletions(-) diff --git a/notebooks/IHaskell.ipynb b/notebooks/IHaskell.ipynb index 80af54a9..2818d75f 100644 --- a/notebooks/IHaskell.ipynb +++ b/notebooks/IHaskell.ipynb @@ -2,7 +2,10 @@ "cells": [ { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "![](https://camo.githubusercontent.com/f6540337202bb3b0c2545d90de0791c9196f9510/68747470733a2f2f7261772e6769746875622e636f6d2f67696269616e736b792f494861736b656c6c2f6d61737465722f68746d6c2f6c6f676f2d36347836342e706e67)\n", "\n", @@ -18,7 +21,11 @@ { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -47,7 +54,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "As you can see, each input cell get an execution number. The first input cell is labeled `In [1]`. Just like in GHCi, the output of the last executed statement or expression is available via the `it` variable - however, in addition, the output of the $n$th cell is available via the `itN` variable. For example, if we wanted to see what the first cell printed, we can go ahead and output that:" ] @@ -55,7 +65,11 @@ { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -73,7 +87,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to simple code cells such as the ones you see, you can also have other types of cells. All of this inline text, for instance, is written using Markdown cells, which support the majority of Github markdown syntax. This lets you embed images and formatting and arbitrary HTML interspersed with your Haskell code. In addition, you can export these notebooks into HTML or even as presentations using `reveal.js`. \n", "\n", @@ -83,7 +100,11 @@ { "cell_type": "code", "execution_count": 3, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -106,7 +127,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to multi-line expressions, IHaskell supports most things that you could put in a standard Haskell file. For example, we can have function bindings without the `let` that GHCi requires. (As long as you group type signatures and their corresponding declarations together, you can use pattern matching and put signatures on your top-level declarations!)" ] @@ -114,7 +138,11 @@ { "cell_type": "code", "execution_count": 4, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -146,7 +174,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "So far we've just looked at pure functions, but nothing is stopping us from doing IO." ] @@ -154,7 +185,11 @@ { "cell_type": "code", "execution_count": 5, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -172,7 +207,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "IHaskell supports most GHC extensions via the `:extension` directive (or any shorthand thereof)." ] @@ -180,7 +218,11 @@ { "cell_type": "code", "execution_count": 6, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -287,7 +329,11 @@ { "cell_type": "code", "execution_count": 7, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- And enable extensions.\n", @@ -297,7 +343,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Data declarations do pretty much what you expect, and work fine on multiple lines. If a declaration turns out to be not quite what you wanted, you can just go back, edit it, and re-evaluate the code cell." ] @@ -305,7 +354,11 @@ { "cell_type": "code", "execution_count": 8, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -329,7 +382,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Although this doesn't hold everywhere, we've tried to keep IHaskell relatively similar to GHCi in terms of naming. So, just like in GHCi, you can inspect types with `:type` (or shorthands):" ] @@ -337,7 +393,11 @@ { "cell_type": "code", "execution_count": 9, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -440,7 +500,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The same goes for the `:info` command. However, unlike GHCi, which simply prints info, the IHaskell notebook brings up a separate pane." ] @@ -448,7 +511,11 @@ { "cell_type": "code", "execution_count": 10, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -463,7 +530,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane that pops up after this is evaluated. However, you can disable the interactive pager, and instead just show the output below the cell:" ] @@ -471,7 +541,11 @@ { "cell_type": "code", "execution_count": 11, - "metadata": {}, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- Only takes effect on later cells, so stick it in its own cell.\n", @@ -481,7 +555,11 @@ { "cell_type": "code", "execution_count": 12, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -613,7 +691,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "We can now write slightly more complicated scripts." ] @@ -621,7 +702,11 @@ { "cell_type": "code", "execution_count": 13, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -649,7 +734,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "This is where the similarities with GHCi end, and the particularly shiny features of IHaskell begin.\n", "\n", @@ -659,7 +747,11 @@ { "cell_type": "code", "execution_count": 14, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "data Color = Red | Green | Blue" @@ -667,7 +759,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If we were playing around with designing GUI applications, for instance, we might want to actually *see* these colors, instead of just seeing the text \"Red\", \"Green\", and \"Blue\" when we are debugging.\n", "\n", @@ -677,7 +772,11 @@ { "cell_type": "code", "execution_count": 15, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "import IHaskell.Display\n", @@ -695,7 +794,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Once we define a custom `display :: a -> IO Display` function, we can simply output a `Color`:" ] @@ -703,7 +805,11 @@ { "cell_type": "code", "execution_count": 16, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -984,7 +1090,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `DisplayData` type has several constructors which let you display your data as plain text, HTML, images (SVG, PNG, JPG), or even as LaTeX code.\n", "\n", @@ -995,7 +1104,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `ihaskell-aeson` package adds a display for [Aeson](http://hackage.haskell.org/package/aeson) JSON `Value` types. These are automatically formatted as JSON, rather than as Haskell values:" ] @@ -1003,12 +1115,16 @@ { "cell_type": "code", "execution_count": 17, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { "text/plain": [ - "Null" + "null" ] }, "metadata": {}, @@ -1017,7 +1133,7 @@ { "data": { "text/plain": [ - "Bool True" + "true" ] }, "metadata": {}, @@ -1026,7 +1142,10 @@ { "data": { "text/plain": [ - "Object (fromList [(\"x\",Number 3.0),(\"y\",Number 2.0)])" + "{\n", + " \"x\": 3,\n", + " \"y\": 2\n", + "}" ] }, "metadata": {}, @@ -1050,7 +1169,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `ihaskell-blaze` package lets you play around with HTML straight from within IHaskell using the [Blaze](http://jaspervdj.be/blaze/tutorial.html) library." ] @@ -1058,7 +1180,11 @@ { "cell_type": "code", "execution_count": 18, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -1287,7 +1413,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The `ihaskell-diagrams` package allows you to experiment with the [diagrams](http://projects.haskell.org/diagrams/) package. It requires the Cairo backend." ] @@ -1295,11 +1424,15 @@ { "cell_type": "code", "execution_count": 19, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { - "image/png": "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" + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1328,7 +1461,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Just like with Diagrams, `ihaskell-charts` allows you to use the [Chart](https://github.com/timbod7/haskell-chart/wiki) library for plotting from within IHaskell. (You will need to install `cairo` as well, which may be a bit of a hassle.)" ] @@ -1336,11 +1472,15 @@ { "cell_type": "code", "execution_count": 20, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { - "image/png": "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" + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1374,7 +1514,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to displaying outputs in a rich format, IHaskell has a bunch of useful features.\n", "\n", @@ -1384,7 +1527,11 @@ { "cell_type": "code", "execution_count": 21, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -1521,7 +1668,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If you're an experienced Haskeller, though, and don't want `hlint` telling you what to do, you can easily turn it off:" ] @@ -1529,7 +1679,11 @@ { "cell_type": "code", "execution_count": 22, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- If hlint annoys you, though, you can turn it off.\n", @@ -1540,7 +1694,11 @@ { "cell_type": "code", "execution_count": 23, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -1559,7 +1717,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "In addition to `hlint` integration, IHaskell also integrates **Hoogle** for documentation searches. IHaskell provides two directives for searching Hoogle. The first of these, `:document` (or shorthands), looks for exact matches." ] @@ -1567,7 +1728,11 @@ { "cell_type": "code", "execution_count": 24, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -1658,243 +1823,14 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "filterM ∷ Applicative m ⇒ (a → m Bool) → [a] → m [a]
This generalizes the list-based filter function.\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a](package base, module Control.Monad)
This generalizes the list-based filter function. \n", "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle v a → Bundle m v a
Yield a monadic stream of elements that satisfy the monadic predicate\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle m v a → Bundle m v a
Drop elements which do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Stream m a → Stream m a
Drop elements which do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ (Monad m, Vector v a) ⇒ (a → m Bool) → v a → m (v a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ (Monad m, Prim a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ (Monad m, Storable a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ (Monad m, Unbox a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → ConduitT a a m ()
Keep only values in the stream passing a given monadic predicate.\n", - "\n", - "Subject to fusion\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → Pipe a a m r
(filterM predicate) only forwards values that satisfy the\n", - "monadic predicate\n", - "\n", - "
\n",
-       "filterM (pure (pure True)) = cat\n",
-       "\n",
-       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
-       "
\n", - "
\n", - "filterM ∷ (a → IO Bool) → InputStream a → IO (InputStream a)
Drops chunks from an input stream if they fail to match a given filter\n", - "predicate. See filter.\n", - "\n", - "Items pushed back to the returned stream are propagated back upstream.\n", - "\n", - "Example:\n", - "\n", - "
\n",
-       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
-       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
-       "[\"the\",\"quick\",\"fox\"]\n",
-       "
\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ (IsSequence seq, Monad m) ⇒ (Element seq → m Bool) → seq → m seq
The monadic version of filter.\n", - "
\n", - "filterM ∷ (Monad m) ⇒ (a → m Bool) → Stream (Of a) m r → Stream (Of a) m r
Skip elements of a stream that fail a monadic test\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ (Monad m, Vector v a) ⇒ a → m Bool → v a → m v a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ Monad m ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ (Monad m, Storable a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ (Monad m, Unbox a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a]
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ (Applicative f) ⇒ (a → f Bool) → [a] → f [a]
See mapM.\n", - "
\n", - "filterM ∷ (Monad m, Vector u a, Vector v b) ⇒ ((a, b) → m Bool) → Vector u v (a, b) → m (Vector u v (a, b))
O(n) Drop elements that do not satisfy the monadic predicate\n", - "
\n", - "filterM ∷ (IsStream t, Monad m) ⇒ (a → m Bool) → t m a → t m a
Same as filter but with a monadic predicate.\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", - "
\n", - "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", "
\n" ], "text/plain": [ - "filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Bundle v a -> Bundle m v a\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle.html#v:filterM\n", - "Yield a monadic stream of elements that satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Bundle m v a -> Bundle m v a\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle-Monadic.html#v:filterM\n", - "Drop elements which do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Stream-Monadic.html#v:filterM\n", - "Drop elements which do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Vector v a) => (a -> m Bool) -> v a -> m (v a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Prim a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Primitive.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Storable a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Storable.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Unbox a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> ConduitT a a m ()\n", - "URL: https://hackage.haskell.org/package/conduit/docs/Data-Conduit-Combinators.html#v:filterM\n", - "Keep only values in the stream passing a given monadic predicate.\n", - "\n", - "Subject to fusion\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Monad m => (a -> m Bool) -> Pipe a a m r\n", - "URL: https://hackage.haskell.org/package/pipes/docs/Pipes-Prelude.html#v:filterM\n", - "(filterM predicate) only forwards values that satisfy the\n", - "monadic predicate\n", - "\n", - "
\n",
-       "filterM (pure (pure True)) = cat\n",
-       "\n",
-       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
-       "
\n", - "\n", - "filterM :: (a -> IO Bool) -> InputStream a -> IO (InputStream a)\n", - "URL: https://hackage.haskell.org/package/io-streams/docs/System-IO-Streams-Combinators.html#v:filterM\n", - "Drops chunks from an input stream if they fail to match a given filter\n", - "predicate. See filter.\n", - "\n", - "Items pushed back to the returned stream are propagated back upstream.\n", - "\n", - "Example:\n", - "\n", - "
\n",
-       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
-       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
-       "[\"the\",\"quick\",\"fox\"]\n",
-       "
\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/protolude/docs/Protolude-Monad.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: (IsSequence seq, Monad m) => (Element seq -> m Bool) -> seq -> m seq\n", - "URL: https://hackage.haskell.org/package/mono-traversable/docs/Data-Sequences.html#v:filterM\n", - "The monadic version of filter.\n", - "\n", - "filterM :: (Monad m) => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m r\n", - "URL: https://hackage.haskell.org/package/streaming/docs/Streaming-Prelude.html#v:filterM\n", - "Skip elements of a stream that fail a monadic test\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: (Monad m, Vector v a) => a -> m Bool -> v a -> m v a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Monad m => a -> m Bool -> Vector a -> m Vector a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Boxed.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Storable a) => a -> m Bool -> Vector a -> m Vector a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Storable.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (Monad m, Unbox a) => a -> m Bool -> Vector a -> m Vector a\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Unboxed.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", "filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/yjtools/docs/Control-Monad-Tools.html#v:filterM\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/universum/docs/Universum-Monad-Reexport.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: (Applicative f) => (a -> f Bool) -> [a] -> f [a]\n", - "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:filterM\n", - "See mapM.\n", - "\n", - "filterM :: (Monad m, Vector u a, Vector v b) => ((a, b) -> m Bool) -> Vector u v (a, b) -> m (Vector u v (a, b))\n", - "URL: https://hackage.haskell.org/package/hybrid-vectors/docs/Data-Vector-Hybrid.html#v:filterM\n", - "O(n) Drop elements that do not satisfy the monadic predicate\n", - "\n", - "filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a\n", - "URL: https://hackage.haskell.org/package/streamly/docs/Streamly-Prelude.html#v:filterM\n", - "Same as filter but with a monadic predicate.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/control-monad-free/docs/Control-Monad-Free.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:filterM\n", - "This generalizes the list-based filter function.\n", - "\n", - "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", - "URL: https://hackage.haskell.org/package/relude/docs/Relude-Monad-Reexport.html#v:filterM\n", - "This generalizes the list-based filter function." + "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:filterM\n", + "This generalizes the list-based filter function." ] }, "metadata": {}, @@ -1907,7 +1843,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature. This will show you documentation for things that match the desired type signature, as demonstrated below. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations." ] @@ -1915,7 +1854,11 @@ { "cell_type": "code", "execution_count": 25, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": {}, @@ -2006,1187 +1949,281 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", + "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", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", "
\n", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\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", - "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", + "
\n", + "
For example,\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
We can combine multiple primitives using >*< multiple times.\n", "
\n", - "zipExact ∷ Partial ⇒ [a] → [b] → [(a, b)]
\n",
-       "zipExact xs ys =\n",
-       "| length xs == length ys = zip xs ys\n",
-       "| otherwise              = error \"some message\"\n",
-       "
\n", + "
\n", + "
> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "shrinkState ∷ ShrinkState s a ⇒ a → s → [(a, s)](package QuickCheck, module Test.QuickCheck.Modifiers)
\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", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
* The entire string prior to the kth match (i.e. the prefix)\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
* The kth match, followed by the remainder of the string\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
Examples:\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "(+*+) ∷ [a] → [b] → [(a, b)]
Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", - "lists, produce a single list such that whenever v and\n", - "w have finite indices in the input lists, (v,w) has\n", - "finite index in the output list. Lower indices occur as the\n", - "fst part of the tuple more frequently, but not exponentially\n", - "so.\n", + "
\n", + "
The needle parameter may not be empty. \n", "
\n", - "unfairCartesianProduct ∷ [a] → [b] → [(a, b)]
Very unfair 2-way Cartesian product: same guarantee as the slightly\n", - "unfair one, except that lower indices may occur as the fst\n", - "part of the tuple exponentially more frequently. This mainly exists as\n", - "a specification to test against.\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\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", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
* The entire string prior to the kth match (i.e. the prefix)\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
* The kth match, followed by the remainder of the string\n", "
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "zip ∷ [a] → [b] → [(a, b)]
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
Examples:\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
This function is strict in its first argument, and lazy in its second.\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", + "
\n", + "
The needle parameter may not be empty. \n", "
\n", - "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", "
\n", - "zipLazy ∷ [a] → [b] → [(a, b)]
zipLazy is a kind of zip that is lazy in the second list\n", - "(observe the ~)\n", + "genLNodes ∷ Enum a ⇒ a → Int → [LNode a](package fgl, module Data.Graph.Inductive.Example)
generate list of labeled nodes \n", "
\n", - "concurrently ∷ MonadBaseControl IO m ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\n", "
\n", - "concurrently ∷ ∀ m a b . (MonadBaseControl IO m, Forall (Pure m)) ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\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", - "pairADefault ∷ Applicative f ⇒ f a → f b → f (a, b)
Default '>*< implementation for non-invertible\n", - "Applicatives.\n", "
\n", - "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", + "threadList ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", + "threadList' ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", + "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "pair ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
Pair two samples. It's like zip but requires that both samples\n", - "have equal size.\n", "
\n", - "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", + "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", "
\n", - "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", - "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", + "mapAccumR ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "zip ∷ Sequence s ⇒ s a → s b → s (a, b)
Combine two sequences into a sequence of pairs. If the sequences are\n", - "different lengths, the excess elements of the longer sequence is\n", - "discarded.\n", - "\n", - "
\n",
-       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
-       "where j = min {n,m}\n",
-       "
\n", - "\n", - "Axioms:\n", - "\n", - "
    \n", - "
  • zip xs ys = zipWith (,) xs ys
  • \n", - "
\n", - "\n", - "This function is always unambiguous.\n", - "\n", - "Default running time: O( min( n1, n2 ) )\n", "
\n", - "zipUsingLview ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", - "zipUsingLists ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", - "concurrently ∷ MonadConc m ⇒ m a → m b → m (a, b)
Run two MonadConc actions concurrently, and return both\n", - "results. If either action throws an exception at any time, then the\n", - "other action is cancelled, and the exception is re-thrown by\n", - "concurrently.\n", - "\n", - "
\n",
-       "concurrently left right =\n",
-       "withAsync left $ \\a ->\n",
-       "withAsync right $ \\b ->\n",
-       "waitBoth a b\n",
-       "
\n", + "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "mzipRep ∷ Representable f ⇒ f a → f b → f (a, b)
\n", - "box ∷ Graph g ⇒ g a → g b → g (a, b)
Compute the Cartesian product of graphs. Complexity: O(s1 *\n", - "s2) time, memory and size, where s1 and s2 are the\n", - "sizes of the given graphs.\n", - "\n", - "
\n",
-       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
-       ", ((0,'a'), (1,'a'))\n",
-       ", ((0,'b'), (1,'b'))\n",
-       ", ((1,'a'), (1,'b')) ]\n",
-       "
\n", - "\n", - "Up to an isomorphism between the resulting vertex types, this\n", - "operation is commutative, associative,\n", - "distributes over overlay, has singleton graphs as\n", - "identities and empty as the annihilating zero.\n", - "Below ~~ stands for the equality up to an isomorphism, e.g.\n", - "(x, ()) ~~ x.\n", - "\n", - "
\n",
-       "box x y               ~~ box y x\n",
-       "box x (box y z)       ~~ box (box x y) z\n",
-       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
-       "box x (vertex ())     ~~ x\n",
-       "box x empty           ~~ empty\n",
-       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
-       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
-       "
\n", "
\n", - "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
-       "divided = divide id\n",
-       "
\n", + "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", "
\n", - "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
The RecordInputType divisible (contravariant) functor allows\n", - "you to build an InputType injector for a Dhall record.\n", - "\n", - "For example, let's take the following Haskell data type:\n", - "\n", - "
\n",
-       "data Project = Project\n",
-       "{ projectName :: Text\n",
-       ", projectDescription :: Text\n",
-       ", projectStars :: Natural\n",
-       "}\n",
-       "
\n", - "\n", - "And assume that we have the following Dhall record that we would like\n", - "to parse as a Project:\n", - "\n", - "
\n",
-       "{ name =\n",
-       "\"dhall-haskell\"\n",
-       ", description =\n",
-       "\"A configuration language guaranteed to terminate\"\n",
-       ", stars =\n",
-       "289\n",
-       "}\n",
-       "
\n", - "\n", - "Our injector has type InputType Project, but we can't\n", - "build that out of any smaller injectors, as InputTypes cannot\n", - "be combined (they are only Contravariants). However, we can use\n", - "an InputRecordType to build an InputType for\n", - "Project:\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputFieldWith \"name\" inject\n",
-       ">*< inputFieldWith \"description\" inject\n",
-       ">*< inputFieldWith \"stars\" inject\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Or, since we are simply using the Inject instance to inject\n", - "each field, we could write\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputField \"name\"\n",
-       ">*< inputField \"description\"\n",
-       ">*< inputField \"stars\"\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Infix divided\n", "
\n", - "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
-       "divided = divide id\n",
-       "
\n", + "mapAccumR ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", "
\n", - "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", - "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", + "mapAccumL ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", "
\n", - "contrazip2 ∷ Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", - "contrazip2 ∷ ∀ f a1 a2 . Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", - "pair ∷ Sized f ⇒ f a → f b → f (a, b)
Default: pair a b = (,) $ a * b.\n", "
\n", - "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
A pairing/concatenation operator for builder primitives, both bounded\n", - "and fixed size.\n", - "\n", - "For example,\n", - "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
-       "
\n", - "\n", - "We can combine multiple primitives using >*< multiple\n", - "times.\n", - "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
-       "
\n", + "mapAccumR ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", "
\n", - "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
Merge two functors into a tuple, analogous to liftA2\n", - "(,). (Sometimes known as **.)\n", "
\n", - "zip ∷ List l ⇒ l a → l b → l (a, b)
\n", - "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", - "zip ∷ (Zip f) ⇒ f a → f b → f (a, b)
\n", - "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", - "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", - "mzip ∷ MonadZip m ⇒ m a → m b → m (a, b)
\n", - "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\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", - "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", "
\n", - "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "breakSubstring ∷ ByteString → ByteString → (ByteString, ByteString)(package bytestring, module Data.ByteString)
otherwise -> Just (length x) \n", "
\n", - "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "
For example, to tokenise a string, dropping delimiters:\n", "
\n", - "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "
> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", + "> \n", "
\n", - "biunfold ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Given a way to generate elements, return a way to generate structures\n", - "containing those elements.\n", + "
\n", + "
To skip to the first occurence of a string:\n", "
\n", - "biunfoldBF ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Breadth-first unfold, which orders the result by the number of\n", - "choose calls.\n", + "
\n", + "
> snd (breakSubstring x y)\n", "
\n", - "deserializeWith2 ∷ (Serial2 f, MonadGet m) ⇒ m a → m b → m (f a b)
\n", - "biunfoldRestrict ∷ (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) ⇒ f a → f b → f (t a b)
\n", - "biunfoldRestrictBF ∷ (BiunfoldableR p q t, Unfolder f, p a, q b) ⇒ f a → f b → f (t a b)
\n", - "mesh ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a mesh graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", - "\n", - "
\n",
-       "mesh xs     []   == empty\n",
-       "mesh []     ys   == empty\n",
-       "mesh [x]    [y]  == vertex (x, y)\n",
-       "mesh xs     ys   == box (path xs) (path ys)\n",
-       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
-       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
-       "
\n", + "
\n", + "
To take the parts of a string before a delimiter:\n", "
\n", - "torus ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a torus graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", - "\n", - "
\n",
-       "torus xs    []   == empty\n",
-       "torus []    ys   == empty\n",
-       "torus [x]   [y]  == edge (x,y) (x,y)\n",
-       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
-       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
-       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
-       "
\n", + "
\n", + "
> fst (breakSubstring x y) \n", "
\n", - "zipExactMay ∷ [a] → [b] → Maybe [(a, b)]
\n" + "
\n", + "breakOn ∷ Text → Text → (Text, Text)(package text, module Data.Text)
O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", + "
\n", + "
\n", + "
Examples:\n", + "
\n", + "
\n", + "
> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", + "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", + "
\n", + "
\n", + "
Laws:\n", + "
\n", + "
\n", + "
> append prefix match == haystack\n", + "> \n", + "
\n", + "
\n", + "
If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", + "
\n", + "
\n", + "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m). \n", + "
\n", + "
\n" ], "text/plain": [ "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/Data-List.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/GHC-List.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base/docs/GHC-OldList.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "\n", - "
\n",
-       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
-       "
\n", - "\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded:\n", - "\n", - "
\n",
-       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
-       "zip [1, 2] ['a'] = [(1, 'a')]\n",
-       "
\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "zip _|_ [] = _|_\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/hspec/docs/Test-Hspec-Discover.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zipExact :: Partial => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExact\n", - "
\n",
-       "zipExact xs ys =\n",
-       "| length xs == length ys = zip xs ys\n",
-       "| otherwise              = error \"some message\"\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/base-compat/docs/Prelude-Compat.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude-Base.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-List.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/fay-base/docs/Prelude.html#v:zip\n", - "\n", - "(+*+) :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:-43--42--43-\n", - "Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", - "lists, produce a single list such that whenever v and\n", - "w have finite indices in the input lists, (v,w) has\n", - "finite index in the output list. Lower indices occur as the\n", - "fst part of the tuple more frequently, but not exponentially\n", - "so.\n", - "\n", - "unfairCartesianProduct :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:unfairCartesianProduct\n", - "Very unfair 2-way Cartesian product: same guarantee as the slightly\n", - "unfair one, except that lower indices may occur as the fst\n", - "part of the tuple exponentially more frequently. This mainly exists as\n", - "a specification to test against.\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/universum/docs/Universum-List-Reexport.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/prelude-compat/docs/Data-List2010.html#v:zip\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/prelude-compat/docs/Prelude2010.html#v:zip\n", - "\n", - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq-ListSeq.html#v:zip\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/intro/docs/Intro.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zip :: () => [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/relude/docs/Relude-List-Reexport.html#v:zip\n", - "zip takes two lists and returns a list of corresponding pairs.\n", - "If one input list is short, excess elements of the longer list are\n", - "discarded.\n", - "\n", - "zip is right-lazy:\n", - "\n", - "
\n",
-       "zip [] _|_ = []\n",
-       "
\n", - "\n", - "zipLazy :: [a] -> [b] -> [(a, b)]\n", - "URL: https://hackage.haskell.org/package/ghc/docs/Util.html#v:zipLazy\n", - "zipLazy is a kind of zip that is lazy in the second list\n", - "(observe the ~)\n", - "\n", - "concurrently :: MonadBaseControl IO m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted.html#v:concurrently\n", - "Generalized version of concurrently.\n", - "\n", - "concurrently :: forall m a b . (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted-Safe.html#v:concurrently\n", - "Generalized version of concurrently.\n", - "\n", - "pairADefault :: Applicative f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:pairADefault\n", - "Default '>*< implementation for non-invertible\n", - "Applicatives.\n", - "\n", - "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", - "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:zip\n", - "O(min(m,n)) Zip two vectors\n", - "\n", - "pair :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", - "URL: https://hackage.haskell.org/package/statistics/docs/Statistics-Sample.html#v:pair\n", - "Pair two samples. It's like zip but requires that both samples\n", - "have equal size.\n", - "\n", - "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", - "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:zip\n", - "O(min(m,n)) Zip two vectors\n", - "\n", - "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/unliftio/docs/UnliftIO-Async.html#v:concurrently\n", - "Unlifted concurrently.\n", - "\n", - "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/yesod-websockets/docs/Yesod-WebSockets.html#v:concurrently\n", - "Unlifted concurrently.\n", - "\n", - "zip :: Sequence s => s a -> s b -> s (a, b)\n", - "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq.html#v:zip\n", - "Combine two sequences into a sequence of pairs. If the sequences are\n", - "different lengths, the excess elements of the longer sequence is\n", - "discarded.\n", - "\n", - "
\n",
-       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
-       "where j = min {n,m}\n",
-       "
\n", - "\n", - "Axioms:\n", - "\n", - "
    \n", - "
  • zip xs ys = zipWith (,) xs ys
  • \n", - "
\n", - "\n", - "This function is always unambiguous.\n", - "\n", - "Default running time: O( min( n1, n2 ) )\n", - "\n", - "zipUsingLview :: Sequence s => s a -> s b -> s (a, b)\n", - "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLview\n", - "\n", - "zipUsingLists :: Sequence s => s a -> s b -> s (a, b)\n", - "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLists\n", - "\n", - "concurrently :: MonadConc m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/concurrency/docs/Control-Concurrent-Classy-Async.html#v:concurrently\n", - "Run two MonadConc actions concurrently, and return both\n", - "results. If either action throws an exception at any time, then the\n", - "other action is cancelled, and the exception is re-thrown by\n", - "concurrently.\n", - "\n", - "
\n",
-       "concurrently left right =\n",
-       "withAsync left $ \\a ->\n",
-       "withAsync right $ \\b ->\n",
-       "waitBoth a b\n",
-       "
\n", - "\n", - "mzipRep :: Representable f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/adjunctions/docs/Data-Functor-Rep.html#v:mzipRep\n", - "\n", - "box :: Graph g => g a -> g b -> g (a, b)\n", - "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:box\n", - "Compute the Cartesian product of graphs. Complexity: O(s1 *\n", - "s2) time, memory and size, where s1 and s2 are the\n", - "sizes of the given graphs.\n", - "\n", - "
\n",
-       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
-       ", ((0,'a'), (1,'a'))\n",
-       ", ((0,'b'), (1,'b'))\n",
-       ", ((1,'a'), (1,'b')) ]\n",
-       "
\n", - "\n", - "Up to an isomorphism between the resulting vertex types, this\n", - "operation is commutative, associative,\n", - "distributes over overlay, has singleton graphs as\n", - "identities and empty as the annihilating zero.\n", - "Below ~~ stands for the equality up to an isomorphism, e.g.\n", - "(x, ()) ~~ x.\n", - "\n", - "
\n",
-       "box x y               ~~ box y x\n",
-       "box x (box y z)       ~~ box (box x y) z\n",
-       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
-       "box x (vertex ())     ~~ x\n",
-       "box x empty           ~~ empty\n",
-       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
-       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
-       "
\n", - "\n", - "divided :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/contravariant/docs/Data-Functor-Contravariant-Divisible.html#v:divided\n", - "
\n",
-       "divided = divide id\n",
-       "
\n", - "\n", - "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/dhall/docs/Dhall.html#v:-62--42--60-\n", - "The RecordInputType divisible (contravariant) functor allows\n", - "you to build an InputType injector for a Dhall record.\n", - "\n", - "For example, let's take the following Haskell data type:\n", - "\n", - "
\n",
-       "data Project = Project\n",
-       "{ projectName :: Text\n",
-       ", projectDescription :: Text\n",
-       ", projectStars :: Natural\n",
-       "}\n",
-       "
\n", - "\n", - "And assume that we have the following Dhall record that we would like\n", - "to parse as a Project:\n", - "\n", - "
\n",
-       "{ name =\n",
-       "\"dhall-haskell\"\n",
-       ", description =\n",
-       "\"A configuration language guaranteed to terminate\"\n",
-       ", stars =\n",
-       "289\n",
-       "}\n",
-       "
\n", - "\n", - "Our injector has type InputType Project, but we can't\n", - "build that out of any smaller injectors, as InputTypes cannot\n", - "be combined (they are only Contravariants). However, we can use\n", - "an InputRecordType to build an InputType for\n", - "Project:\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputFieldWith \"name\" inject\n",
-       ">*< inputFieldWith \"description\" inject\n",
-       ">*< inputFieldWith \"stars\" inject\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Or, since we are simply using the Inject instance to inject\n", - "each field, we could write\n", - "\n", - "
\n",
-       "injectProject :: InputType Project\n",
-       "injectProject =\n",
-       "inputRecord\n",
-       "(  adapt >$< inputField \"name\"\n",
-       ">*< inputField \"description\"\n",
-       ">*< inputField \"stars\"\n",
-       ")\n",
-       "where\n",
-       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
-       "
\n", - "\n", - "Infix divided\n", - "\n", - "divided :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:divided\n", - "
\n",
-       "divided = divide id\n",
-       "
\n", - "\n", - "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:-62--42--60-\n", - "An alias to divided.\n", - "\n", - "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras.html#v:-62--42--60-\n", - "An alias to divided.\n", - "\n", - "contrazip2 :: Divisible f => f a1 -> f a2 -> f (a1, a2)\n", - "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:contrazip2\n", - "\n", - "contrazip2 :: forall f a1 a2 . Divisible f => f a1 -> f a2 -> f (a1, a2)\n", - "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras-Contrazip.html#v:contrazip2\n", - "\n", - "pair :: Sized f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/size-based/docs/Control-Sized.html#v:pair\n", - "Default: pair a b = (,) $ a * b.\n", - "\n", + "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:zip\n", + "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", "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/bytestring/docs/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", - "A pairing/concatenation operator for builder primitives, both bounded\n", - "and fixed size.\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", + "A pairing/concatenation operator for builder primitives, both bounded and fixed size.\n", "\n", "For example,\n", "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
-       "
\n", + "> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", "\n", - "We can combine multiple primitives using >*< multiple\n", - "times.\n", + "We can combine multiple primitives using >*< multiple times.\n", "\n", - "
\n",
-       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
-       "
\n", + "> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", + "shrinkState :: ShrinkState s a => a -> s -> [(a, s)]\n", + "URL: http://hackage.haskell.org/packages/archive/QuickCheck/latest/doc/html/Test-QuickCheck-Modifiers.html#v:shrinkState\n", "\n", - "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:-62--42--60-\n", - "Merge two functors into a tuple, analogous to liftA2\n", - "(,). (Sometimes known as **.)\n", + "breakOnAll :: Text -> Text -> [(Text, Text)]\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOnAll\n", + "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", "\n", - "zip :: List l => l a -> l b -> l (a, b)\n", - "URL: https://hackage.haskell.org/package/List/docs/Data-List-Class.html#v:zip\n", + "* The entire string prior to the kth match (i.e. the prefix)\n", + "* The kth match, followed by the remainder of the string\n", "\n", - "zip :: Zip f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/classy-prelude/docs/ClassyPrelude.html#v:zip\n", + "Examples:\n", "\n", - "zip :: (Zip f) => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/non-empty/docs/Data-NonEmpty-Class.html#v:zip\n", + "> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "\n", - "zip :: Zip f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/keys/docs/Data-Key.html#v:zip\n", + "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "\n", - "zip :: Zip f => f a -> f b -> f (a, b)\n", - "URL: https://hackage.haskell.org/package/chunked-data/docs/Data-ChunkedZip.html#v:zip\n", + "The needle parameter may not be empty. \n", + "breakOnAll :: Text -> Text -> [(Text, Text)]\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text-Lazy.html#v:breakOnAll\n", + "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", "\n", - "mzip :: MonadZip m => m a -> m b -> m (a, b)\n", - "URL: https://hackage.haskell.org/package/base/docs/Control-Monad-Zip.html#v:mzip\n", + "* The entire string prior to the kth match (i.e. the prefix)\n", + "* The kth match, followed by the remainder of the string\n", "\n", - "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:projectZip\n", - "Zipping projections.\n", + "Examples:\n", "\n", - "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:-62--60-\n", - "Binary operator the same as projectZip.\n", + "> breakOnAll \"::\" \"\"\n", + "> ==> []\n", + "> breakOnAll \"/\" \"a/b/c/\"\n", + "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", "\n", - "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:projectZip\n", - "Zipping projections.\n", + "This function is strict in its first argument, and lazy in its second.\n", "\n", - "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:-62--60-\n", - "Binary operator the same as projectZip.\n", + "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", "\n", - "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", - "URL: https://hackage.haskell.org/package/relational-record/docs/Database-Relational-Documentation.html#v:-62--60-\n", - "Binary operator the same as projectZip.\n", + "The needle parameter may not be empty. \n", + "genLNodes :: Enum a => a -> Int -> [LNode a]\n", + "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Example.html#v:genLNodes\n", + "generate list of labeled nodes \n", + "gmapAccumT :: Data d => (forall e. Data e => a -> e -> (a, e)) -> a -> d -> (a, d)\n", + "URL: http://hackage.haskell.org/packages/archive/syb/latest/doc/html/Data-Generics-Twins.html#v:gmapAccumT\n", + "gmapT with accumulation \n", + "threadList :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", + "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList\n", "\n", - "biunfold :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfold\n", - "Given a way to generate elements, return a way to generate structures\n", - "containing those elements.\n", + "threadList' :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", + "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList-39-\n", "\n", - "biunfoldBF :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfoldBF\n", - "Breadth-first unfold, which orders the result by the number of\n", - "choose calls.\n", + "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "mapAccumR :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumR\n", + "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy-Char8.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumL\n", + "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "mapAccumR :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumR\n", + "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "mapAccumL :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumL\n", + "O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", + "mapAccumR :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumR\n", + "The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", + "execRWS :: RWS r w s a -> r -> s -> (s, w)\n", + "URL: http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html#v:execRWS\n", + "Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n", + "breakSubstring :: ByteString -> ByteString -> (ByteString, ByteString)\n", + "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:breakSubstring\n", + "otherwise -> Just (length x) \n", "\n", - "deserializeWith2 :: (Serial2 f, MonadGet m) => m a -> m b -> m (f a b)\n", - "URL: https://hackage.haskell.org/package/bytes/docs/Data-Bytes-Serial.html#v:deserializeWith2\n", + "For example, to tokenise a string, dropping delimiters:\n", "\n", - "biunfoldRestrict :: (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrict\n", + "> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", + "> \n", "\n", - "biunfoldRestrictBF :: (BiunfoldableR p q t, Unfolder f, p a, q b) => f a -> f b -> f (t a b)\n", - "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrictBF\n", + "To skip to the first occurence of a string:\n", "\n", - "mesh :: Graph g => [a] -> [b] -> g (a, b)\n", - "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:mesh\n", - "Construct a mesh graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", + "> snd (breakSubstring x y)\n", "\n", - "
\n",
-       "mesh xs     []   == empty\n",
-       "mesh []     ys   == empty\n",
-       "mesh [x]    [y]  == vertex (x, y)\n",
-       "mesh xs     ys   == box (path xs) (path ys)\n",
-       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
-       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
-       "
\n", + "To take the parts of a string before a delimiter:\n", "\n", - "torus :: Graph g => [a] -> [b] -> g (a, b)\n", - "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:torus\n", - "Construct a torus graph from two lists of vertices. Complexity:\n", - "O(L1 * L2) time, memory and size, where L1 and L2\n", - "are the lengths of the given lists.\n", + "> fst (breakSubstring x y) \n", + "breakOn :: Text -> Text -> (Text, Text)\n", + "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOn\n", + "O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", "\n", - "
\n",
-       "torus xs    []   == empty\n",
-       "torus []    ys   == empty\n",
-       "torus [x]   [y]  == edge (x,y) (x,y)\n",
-       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
-       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
-       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
-       "
\n", + "Examples:\n", "\n", - "zipExactMay :: [a] -> [b] -> Maybe [(a, b)]\n", - "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExactMay" + "> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", + "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", + "\n", + "Laws:\n", + "\n", + "> append prefix match == haystack\n", + "> \n", + "\n", + "If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", + "\n", + "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m)." ] }, "metadata": {}, @@ -3199,7 +2236,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "If you need a refresher on all of the options, you can just use `:help`:" ] @@ -3207,7 +2247,11 @@ { "cell_type": "code", "execution_count": 26, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3244,7 +2288,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "All of the code you normally put into IHaskell is (like in GHCi) interpreted. However, sometimes you've perfected a function, and now need it to run faster. In that case, you can go ahead and define a module in a single cell. As long as your module has a module header along the lines of `module Name where`, IHaskell will recognize it as a module. It will create the file `A/B.hs`, compile it, and load it. " ] @@ -3252,7 +2299,11 @@ { "cell_type": "code", "execution_count": 27, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [], "source": [ "-- If your code isn't running fast enough, you can just put it into a module.\n", @@ -3265,7 +2316,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Note that the module is by default imported unqualified, as though you had typed `import A.B`." ] @@ -3273,7 +2327,11 @@ { "cell_type": "code", "execution_count": 28, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3302,7 +2360,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Note that since a new module is imported, all previous bound identifiers are now unbound. For instance, we no longer have access to the `f` function from before:" ] @@ -3310,7 +2371,11 @@ { "cell_type": "code", "execution_count": 29, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3412,7 +2477,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "However, if you re-import this module with another import statement, the original implicit import goes away." ] @@ -3420,7 +2488,11 @@ { "cell_type": "code", "execution_count": 30, - "metadata": {}, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, "outputs": [ { "data": { @@ -3450,7 +2522,10 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "deletable": true, + "editable": true + }, "source": [ "Thanks!\n", "---\n", @@ -3474,8 +2549,7 @@ "codemirror_mode": "ihaskell", "file_extension": ".hs", "name": "haskell", - "pygments_lexer": "Haskell", - "version": "8.4.3" + "version": "8.0.2" }, "latex_envs": { "bibliofile": "biblio.bib", @@ -3496,5 +2570,5 @@ } }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 0 } From 03907a998cc5404df2306689e8fe173691797de7 Mon Sep 17 00:00:00 2001 From: Thomas Peiselt Date: Fri, 2 Nov 2018 14:34:00 +0100 Subject: [PATCH 10/10] Update demo notebook after changes to the hoogle search. --- notebooks/IHaskell.ipynb | 1877 ++++++++++++++++++++++++++++---------- 1 file changed, 1403 insertions(+), 474 deletions(-) diff --git a/notebooks/IHaskell.ipynb b/notebooks/IHaskell.ipynb index 2818d75f..7dcae964 100644 --- a/notebooks/IHaskell.ipynb +++ b/notebooks/IHaskell.ipynb @@ -2,10 +2,7 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "![](https://camo.githubusercontent.com/f6540337202bb3b0c2545d90de0791c9196f9510/68747470733a2f2f7261772e6769746875622e636f6d2f67696269616e736b792f494861736b656c6c2f6d61737465722f68746d6c2f6c6f676f2d36347836342e706e67)\n", "\n", @@ -21,11 +18,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -54,10 +47,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "As you can see, each input cell get an execution number. The first input cell is labeled `In [1]`. Just like in GHCi, the output of the last executed statement or expression is available via the `it` variable - however, in addition, the output of the $n$th cell is available via the `itN` variable. For example, if we wanted to see what the first cell printed, we can go ahead and output that:" ] @@ -65,11 +55,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -87,10 +73,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to simple code cells such as the ones you see, you can also have other types of cells. All of this inline text, for instance, is written using Markdown cells, which support the majority of Github markdown syntax. This lets you embed images and formatting and arbitrary HTML interspersed with your Haskell code. In addition, you can export these notebooks into HTML or even as presentations using `reveal.js`. \n", "\n", @@ -100,11 +83,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -127,10 +106,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to multi-line expressions, IHaskell supports most things that you could put in a standard Haskell file. For example, we can have function bindings without the `let` that GHCi requires. (As long as you group type signatures and their corresponding declarations together, you can use pattern matching and put signatures on your top-level declarations!)" ] @@ -138,11 +114,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -174,10 +146,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "So far we've just looked at pure functions, but nothing is stopping us from doing IO." ] @@ -185,11 +154,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -207,10 +172,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "IHaskell supports most GHC extensions via the `:extension` directive (or any shorthand thereof)." ] @@ -218,11 +180,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -329,11 +287,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- And enable extensions.\n", @@ -343,10 +297,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Data declarations do pretty much what you expect, and work fine on multiple lines. If a declaration turns out to be not quite what you wanted, you can just go back, edit it, and re-evaluate the code cell." ] @@ -354,11 +305,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -382,10 +329,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Although this doesn't hold everywhere, we've tried to keep IHaskell relatively similar to GHCi in terms of naming. So, just like in GHCi, you can inspect types with `:type` (or shorthands):" ] @@ -393,11 +337,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -500,10 +440,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The same goes for the `:info` command. However, unlike GHCi, which simply prints info, the IHaskell notebook brings up a separate pane." ] @@ -511,11 +448,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -530,10 +463,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane that pops up after this is evaluated. However, you can disable the interactive pager, and instead just show the output below the cell:" ] @@ -541,11 +471,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- Only takes effect on later cells, so stick it in its own cell.\n", @@ -555,11 +481,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -691,10 +613,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "We can now write slightly more complicated scripts." ] @@ -702,11 +621,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -734,10 +649,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "This is where the similarities with GHCi end, and the particularly shiny features of IHaskell begin.\n", "\n", @@ -747,11 +659,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "data Color = Red | Green | Blue" @@ -759,10 +667,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If we were playing around with designing GUI applications, for instance, we might want to actually *see* these colors, instead of just seeing the text \"Red\", \"Green\", and \"Blue\" when we are debugging.\n", "\n", @@ -772,11 +677,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import IHaskell.Display\n", @@ -794,10 +695,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Once we define a custom `display :: a -> IO Display` function, we can simply output a `Color`:" ] @@ -805,11 +703,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1090,10 +984,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `DisplayData` type has several constructors which let you display your data as plain text, HTML, images (SVG, PNG, JPG), or even as LaTeX code.\n", "\n", @@ -1104,10 +995,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-aeson` package adds a display for [Aeson](http://hackage.haskell.org/package/aeson) JSON `Value` types. These are automatically formatted as JSON, rather than as Haskell values:" ] @@ -1115,11 +1003,7 @@ { "cell_type": "code", "execution_count": 17, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1169,10 +1053,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-blaze` package lets you play around with HTML straight from within IHaskell using the [Blaze](http://jaspervdj.be/blaze/tutorial.html) library." ] @@ -1180,11 +1061,7 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1413,10 +1290,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `ihaskell-diagrams` package allows you to experiment with the [diagrams](http://projects.haskell.org/diagrams/) package. It requires the Cairo backend." ] @@ -1424,15 +1298,11 @@ { "cell_type": "code", "execution_count": 19, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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" + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1461,10 +1331,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Just like with Diagrams, `ihaskell-charts` allows you to use the [Chart](https://github.com/timbod7/haskell-chart/wiki) library for plotting from within IHaskell. (You will need to install `cairo` as well, which may be a bit of a hassle.)" ] @@ -1472,15 +1339,11 @@ { "cell_type": "code", "execution_count": 20, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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" + "image/png": "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" }, "metadata": {}, "output_type": "display_data" @@ -1514,10 +1377,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to displaying outputs in a rich format, IHaskell has a bunch of useful features.\n", "\n", @@ -1527,11 +1387,7 @@ { "cell_type": "code", "execution_count": 21, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1668,10 +1524,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you're an experienced Haskeller, though, and don't want `hlint` telling you what to do, you can easily turn it off:" ] @@ -1679,11 +1532,7 @@ { "cell_type": "code", "execution_count": 22, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- If hlint annoys you, though, you can turn it off.\n", @@ -1694,11 +1543,7 @@ { "cell_type": "code", "execution_count": 23, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1717,10 +1562,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to `hlint` integration, IHaskell also integrates **Hoogle** for documentation searches. IHaskell provides two directives for searching Hoogle. The first of these, `:document` (or shorthands), looks for exact matches." ] @@ -1728,11 +1570,7 @@ { "cell_type": "code", "execution_count": 24, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -1823,14 +1661,243 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a](package base, module Control.Monad)
This generalizes the list-based filter function. \n", + "filterM ∷ Applicative m ⇒ (a → m Bool) → [a] → m [a]
This generalizes the list-based filter function.\n", "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle v a → Bundle m v a
Yield a monadic stream of elements that satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Bundle m v a → Bundle m v a
Drop elements which do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Stream m a → Stream m a
Drop elements which do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Vector v a) ⇒ (a → m Bool) → v a → m (v a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Prim a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Storable a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Unbox a) ⇒ (a → m Bool) → Vector a → m (Vector a)
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → ConduitT a a m ()
Keep only values in the stream passing a given monadic predicate.\n", + "\n", + "Subject to fusion\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → Pipe a a m r
(filterM predicate) only forwards values that satisfy the\n", + "monadic predicate\n", + "\n", + "
\n",
+       "filterM (pure (pure True)) = cat\n",
+       "\n",
+       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
+       "
\n", + "
\n", + "filterM ∷ (a → IO Bool) → InputStream a → IO (InputStream a)
Drops chunks from an input stream if they fail to match a given filter\n", + "predicate. See filter.\n", + "\n", + "Items pushed back to the returned stream are propagated back upstream.\n", + "\n", + "Example:\n", + "\n", + "
\n",
+       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
+       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
+       "[\"the\",\"quick\",\"fox\"]\n",
+       "
\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ (IsSequence seq, Monad m) ⇒ (Element seq → m Bool) → seq → m seq
The monadic version of filter.\n", + "
\n", + "filterM ∷ (Monad m) ⇒ (a → m Bool) → Stream (Of a) m r → Stream (Of a) m r
Skip elements of a stream that fail a monadic test\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ (Monad m, Vector v a) ⇒ a → m Bool → v a → m v a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Monad m ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Storable a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (Monad m, Unbox a) ⇒ a → m Bool → Vector a → m Vector a
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Monad m ⇒ (a → m Bool) → [a] → m [a]
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ (Applicative f) ⇒ (a → f Bool) → [a] → f [a]
See mapM.\n", + "
\n", + "filterM ∷ (Monad m, Vector u a, Vector v b) ⇒ ((a, b) → m Bool) → Vector u v (a, b) → m (Vector u v (a, b))
O(n) Drop elements that do not satisfy the monadic predicate\n", + "
\n", + "filterM ∷ (IsStream t, Monad m) ⇒ (a → m Bool) → t m a → t m a
Same as filter but with a monadic predicate.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", + "
\n", + "filterM ∷ Applicative m ⇒ a → m Bool → [a] → m [a]
This generalizes the list-based filter function.\n", "
\n" ], "text/plain": [ + "filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/base/docs/Control-Monad.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Bundle v a -> Bundle m v a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle.html#v:filterM\n", + "Yield a monadic stream of elements that satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Bundle m v a -> Bundle m v a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Bundle-Monadic.html#v:filterM\n", + "Drop elements which do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Fusion-Stream-Monadic.html#v:filterM\n", + "Drop elements which do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Vector v a) => (a -> m Bool) -> v a -> m (v a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Prim a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Primitive.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Storable a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Storable.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Unbox a) => (a -> m Bool) -> Vector a -> m (Vector a)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> ConduitT a a m ()\n", + "URL: https://hackage.haskell.org/package/conduit/docs/Data-Conduit-Combinators.html#v:filterM\n", + "Keep only values in the stream passing a given monadic predicate.\n", + "\n", + "Subject to fusion\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Monad m => (a -> m Bool) -> Pipe a a m r\n", + "URL: https://hackage.haskell.org/package/pipes/docs/Pipes-Prelude.html#v:filterM\n", + "(filterM predicate) only forwards values that satisfy the\n", + "monadic predicate\n", + "\n", + "
\n",
+       "filterM (pure (pure True)) = cat\n",
+       "\n",
+       "filterM (liftA2 (liftA2 (&&)) p1 p2) = filterM p1 >-> filterM p2\n",
+       "
\n", + "\n", + "filterM :: (a -> IO Bool) -> InputStream a -> IO (InputStream a)\n", + "URL: https://hackage.haskell.org/package/io-streams/docs/System-IO-Streams-Combinators.html#v:filterM\n", + "Drops chunks from an input stream if they fail to match a given filter\n", + "predicate. See filter.\n", + "\n", + "Items pushed back to the returned stream are propagated back upstream.\n", + "\n", + "Example:\n", + "\n", + "
\n",
+       "ghci> Streams.fromList [\"the\", \"quick\", \"brown\", \"fox\"] >>=\n",
+       "Streams.filterM (return . (/= \"brown\")) >>= Streams.toList\n",
+       "[\"the\",\"quick\",\"fox\"]\n",
+       "
\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude-Monad.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (IsSequence seq, Monad m) => (Element seq -> m Bool) -> seq -> m seq\n", + "URL: https://hackage.haskell.org/package/mono-traversable/docs/Data-Sequences.html#v:filterM\n", + "The monadic version of filter.\n", + "\n", + "filterM :: (Monad m) => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m r\n", + "URL: https://hackage.haskell.org/package/streaming/docs/Streaming-Prelude.html#v:filterM\n", + "Skip elements of a stream that fail a monadic test\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (Monad m, Vector v a) => a -> m Bool -> v a -> m v a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Monad m => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Boxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Storable a) => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Storable.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (Monad m, Unbox a) => a -> m Bool -> Vector a -> m Vector a\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector-Unboxed.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", "filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]\n", - "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:filterM\n", - "This generalizes the list-based filter function." + "URL: https://hackage.haskell.org/package/yjtools/docs/Control-Monad-Tools.html#v:filterM\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/universum/docs/Universum-Monad-Reexport.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: (Applicative f) => (a -> f Bool) -> [a] -> f [a]\n", + "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:filterM\n", + "See mapM.\n", + "\n", + "filterM :: (Monad m, Vector u a, Vector v b) => ((a, b) -> m Bool) -> Vector u v (a, b) -> m (Vector u v (a, b))\n", + "URL: https://hackage.haskell.org/package/hybrid-vectors/docs/Data-Vector-Hybrid.html#v:filterM\n", + "O(n) Drop elements that do not satisfy the monadic predicate\n", + "\n", + "filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a\n", + "URL: https://hackage.haskell.org/package/streamly/docs/Streamly-Prelude.html#v:filterM\n", + "Same as filter but with a monadic predicate.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/control-monad-free/docs/Control-Monad-Free.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:filterM\n", + "This generalizes the list-based filter function.\n", + "\n", + "filterM :: Applicative m => a -> m Bool -> [a] -> m [a]\n", + "URL: https://hackage.haskell.org/package/relude/docs/Relude-Monad-Reexport.html#v:filterM\n", + "This generalizes the list-based filter function." ] }, "metadata": {}, @@ -1843,10 +1910,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature. This will show you documentation for things that match the desired type signature, as demonstrated below. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations." ] @@ -1854,11 +1918,7 @@ { "cell_type": "code", "execution_count": 25, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": {}, @@ -1949,281 +2009,1187 @@ ".suggestion-name {\n", "font-weight: bold;\n", "}\n", - "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", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\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", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", - "
\n", - "
For example,\n", + "zip ∷ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", + "\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", + "\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "
\n", - "
\n", - "
> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
We can combine multiple primitives using >*< multiple times.\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", + "zipExact ∷ Partial ⇒ [a] → [b] → [(a, b)]
\n",
+       "zipExact xs ys =\n",
+       "| length xs == length ys = zip xs ys\n",
+       "| otherwise              = error \"some message\"\n",
+       "
\n", "
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "shrinkState ∷ ShrinkState s a ⇒ a → s → [(a, s)](package QuickCheck, module Test.QuickCheck.Modifiers)
\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", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
* The entire string prior to the kth match (i.e. the prefix)\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
* The kth match, followed by the remainder of the string\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
Examples:\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
The needle parameter may not be empty. \n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "(+*+) ∷ [a] → [b] → [(a, b)]
Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", + "lists, produce a single list such that whenever v and\n", + "w have finite indices in the input lists, (v,w) has\n", + "finite index in the output list. Lower indices occur as the\n", + "fst part of the tuple more frequently, but not exponentially\n", + "so.\n", "
\n", + "unfairCartesianProduct ∷ [a] → [b] → [(a, b)]
Very unfair 2-way Cartesian product: same guarantee as the slightly\n", + "unfair one, except that lower indices may occur as the fst\n", + "part of the tuple exponentially more frequently. This mainly exists as\n", + "a specification to test against.\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", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
* The entire string prior to the kth match (i.e. the prefix)\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
* The kth match, followed by the remainder of the string\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
Examples:\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ [a] → [b] → [(a, b)]
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
This function is strict in its first argument, and lazy in its second.\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "
\n", - "
The needle parameter may not be empty. \n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", + "zip ∷ () ⇒ [a] → [b] → [(a, b)]
zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", "
\n", - "genLNodes ∷ Enum a ⇒ a → Int → [LNode a](package fgl, module Data.Graph.Inductive.Example)
generate list of labeled nodes \n", + "zipLazy ∷ [a] → [b] → [(a, b)]
zipLazy is a kind of zip that is lazy in the second list\n", + "(observe the ~)\n", "
\n", + "concurrently ∷ MonadBaseControl IO m ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\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", + "concurrently ∷ ∀ m a b . (MonadBaseControl IO m, Forall (Pure m)) ⇒ m a → m b → m (a, b)
Generalized version of concurrently.\n", "
\n", + "pairADefault ∷ Applicative f ⇒ f a → f b → f (a, b)
Default '>*< implementation for non-invertible\n", + "Applicatives.\n", "
\n", - "threadList ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", - "threadList' ∷ (Collect r c) → (Split t i r) → [i] → t → (c, t)(package fgl, module Data.Graph.Inductive.Internal.Thread)
\n", - "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", "
\n", + "pair ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
Pair two samples. It's like zip but requires that both samples\n", + "have equal size.\n", "
\n", - "mapAccumL ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "zip ∷ (Vector v a, Vector v b, Vector v (a, b)) ⇒ v a → v b → v (a, b)
O(min(m,n)) Zip two vectors\n", "
\n", + "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", - "mapAccumR ∷ (acc → Word8 → (acc, Word8)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "concurrently ∷ MonadUnliftIO m ⇒ m a → m b → m (a, b)
Unlifted concurrently.\n", "
\n", + "zip ∷ Sequence s ⇒ s a → s b → s (a, b)
Combine two sequences into a sequence of pairs. If the sequences are\n", + "different lengths, the excess elements of the longer sequence is\n", + "discarded.\n", + "\n", + "
\n",
+       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
+       "where j = min {n,m}\n",
+       "
\n", + "\n", + "Axioms:\n", + "\n", + "
    \n", + "
  • zip xs ys = zipWith (,) xs ys
  • \n", + "
\n", + "\n", + "This function is always unambiguous.\n", + "\n", + "Default running time: O( min( n1, n2 ) )\n", "
\n", - "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Lazy.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", + "zipUsingLview ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", + "zipUsingLists ∷ Sequence s ⇒ s a → s b → s (a, b)
\n", + "concurrently ∷ MonadConc m ⇒ m a → m b → m (a, b)
Run two MonadConc actions concurrently, and return both\n", + "results. If either action throws an exception at any time, then the\n", + "other action is cancelled, and the exception is re-thrown by\n", + "concurrently.\n", + "\n", + "
\n",
+       "concurrently left right =\n",
+       "withAsync left $ \\a ->\n",
+       "withAsync right $ \\b ->\n",
+       "waitBoth a b\n",
+       "
\n", "
\n", + "mzipRep ∷ Representable f ⇒ f a → f b → f (a, b)
\n", + "box ∷ Graph g ⇒ g a → g b → g (a, b)
Compute the Cartesian product of graphs. Complexity: O(s1 *\n", + "s2) time, memory and size, where s1 and s2 are the\n", + "sizes of the given graphs.\n", + "\n", + "
\n",
+       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
+       ", ((0,'a'), (1,'a'))\n",
+       ", ((0,'b'), (1,'b'))\n",
+       ", ((1,'a'), (1,'b')) ]\n",
+       "
\n", + "\n", + "Up to an isomorphism between the resulting vertex types, this\n", + "operation is commutative, associative,\n", + "distributes over overlay, has singleton graphs as\n", + "identities and empty as the annihilating zero.\n", + "Below ~~ stands for the equality up to an isomorphism, e.g.\n", + "(x, ()) ~~ x.\n", + "\n", + "
\n",
+       "box x y               ~~ box y x\n",
+       "box x (box y z)       ~~ box (box x y) z\n",
+       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
+       "box x (vertex ())     ~~ x\n",
+       "box x empty           ~~ empty\n",
+       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
+       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
+       "
\n", "
\n", - "mapAccumL ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", + "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
+       "divided = divide id\n",
+       "
\n", "
\n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
The RecordInputType divisible (contravariant) functor allows\n", + "you to build an InputType injector for a Dhall record.\n", + "\n", + "For example, let's take the following Haskell data type:\n", + "\n", + "
\n",
+       "data Project = Project\n",
+       "{ projectName :: Text\n",
+       ", projectDescription :: Text\n",
+       ", projectStars :: Natural\n",
+       "}\n",
+       "
\n", + "\n", + "And assume that we have the following Dhall record that we would like\n", + "to parse as a Project:\n", + "\n", + "
\n",
+       "{ name =\n",
+       "\"dhall-haskell\"\n",
+       ", description =\n",
+       "\"A configuration language guaranteed to terminate\"\n",
+       ", stars =\n",
+       "289\n",
+       "}\n",
+       "
\n", + "\n", + "Our injector has type InputType Project, but we can't\n", + "build that out of any smaller injectors, as InputTypes cannot\n", + "be combined (they are only Contravariants). However, we can use\n", + "an InputRecordType to build an InputType for\n", + "Project:\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputFieldWith \"name\" inject\n",
+       ">*< inputFieldWith \"description\" inject\n",
+       ">*< inputFieldWith \"stars\" inject\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Or, since we are simply using the Inject instance to inject\n", + "each field, we could write\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputField \"name\"\n",
+       ">*< inputField \"description\"\n",
+       ">*< inputField \"stars\"\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Infix divided\n", "
\n", - "mapAccumR ∷ (acc → Char → (acc, Char)) → acc → ByteString → (acc, ByteString)(package bytestring, module Data.ByteString.Char8)
The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", + "divided ∷ Divisible f ⇒ f a → f b → f (a, b)
\n",
+       "divided = divide id\n",
+       "
\n", "
\n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", - "mapAccumL ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", + "(>*<) ∷ Divisible f ⇒ f a → f b → f (a, b)
An alias to divided.\n", "
\n", + "contrazip2 ∷ Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", + "contrazip2 ∷ ∀ f a1 a2 . Divisible f ⇒ f a1 → f a2 → f (a1, a2)
\n", + "pair ∷ Sized f ⇒ f a → f b → f (a, b)
Default: pair a b = (,) $ a * b.\n", "
\n", - "mapAccumR ∷ (a → Char → (a, Char)) → a → Text → (a, Text)(package text, module Data.Text)
The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", - "
\n", - "
\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", - "breakSubstring ∷ ByteString → ByteString → (ByteString, ByteString)(package bytestring, module Data.ByteString)
otherwise -> Just (length x) \n", - "
\n", - "
\n", - "
For example, to tokenise a string, dropping delimiters:\n", - "
\n", - "
\n", - "
> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", - "> \n", - "
\n", - "
\n", - "
To skip to the first occurence of a string:\n", - "
\n", - "
\n", - "
> snd (breakSubstring x y)\n", - "
\n", - "
\n", - "
To take the parts of a string before a delimiter:\n", - "
\n", - "
\n", - "
> fst (breakSubstring x y) \n", - "
\n", - "
\n", - "breakOn ∷ Text → Text → (Text, Text)(package text, module Data.Text)
O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", - "
\n", - "
\n", - "
Examples:\n", - "
\n", - "
\n", - "
> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", - "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", - "
\n", - "
\n", - "
Laws:\n", - "
\n", - "
\n", - "
> append prefix match == haystack\n", - "> \n", - "
\n", - "
\n", - "
If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", - "
\n", - "
\n", - "
In (unlikely) bad cases, this function's time complexity degrades towards O(n*m). \n", - "
\n", - "
\n" - ], - "text/plain": [ - "zip :: [a] -> [b] -> [(a, b)]\n", - "URL: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:zip\n", - "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", - "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", - "A pairing/concatenation operator for builder primitives, both bounded and fixed size.\n", + "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
A pairing/concatenation operator for builder primitives, both bounded\n", + "and fixed size.\n", "\n", "For example,\n", "\n", - "> toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
+       "
\n", "\n", - "We can combine multiple primitives using >*< multiple times.\n", + "We can combine multiple primitives using >*< multiple\n", + "times.\n", "\n", - "> toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\" \n", - "shrinkState :: ShrinkState s a => a -> s -> [(a, s)]\n", - "URL: http://hackage.haskell.org/packages/archive/QuickCheck/latest/doc/html/Test-QuickCheck-Modifiers.html#v:shrinkState\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
+       "
\n", + "
\n", + "(>*<) ∷ Monoidal f ⇒ f a → f b → f (a, b)
Merge two functors into a tuple, analogous to liftA2\n", + "(,). (Sometimes known as **.)\n", + "
\n", + "zip ∷ List l ⇒ l a → l b → l (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "zip ∷ (Zip f) ⇒ f a → f b → f (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "zip ∷ Zip f ⇒ f a → f b → f (a, b)
\n", + "mzip ∷ MonadZip m ⇒ m a → m b → m (a, b)
\n", + "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "projectZip ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Zipping projections.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "(><) ∷ ProductIsoApplicative p ⇒ p a → p b → p (a, b)
Binary operator the same as projectZip.\n", + "
\n", + "biunfold ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Given a way to generate elements, return a way to generate structures\n", + "containing those elements.\n", + "
\n", + "biunfoldBF ∷ (Biunfoldable t, Unfolder f) ⇒ f a → f b → f (t a b)
Breadth-first unfold, which orders the result by the number of\n", + "choose calls.\n", + "
\n", + "deserializeWith2 ∷ (Serial2 f, MonadGet m) ⇒ m a → m b → m (f a b)
\n", + "biunfoldRestrict ∷ (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) ⇒ f a → f b → f (t a b)
\n", + "biunfoldRestrictBF ∷ (BiunfoldableR p q t, Unfolder f, p a, q b) ⇒ f a → f b → f (t a b)
\n", + "mesh ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a mesh graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", "\n", - "breakOnAll :: Text -> Text -> [(Text, Text)]\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOnAll\n", - "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "
\n",
+       "mesh xs     []   == empty\n",
+       "mesh []     ys   == empty\n",
+       "mesh [x]    [y]  == vertex (x, y)\n",
+       "mesh xs     ys   == box (path xs) (path ys)\n",
+       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
+       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
+       "
\n", + "
\n", + "torus ∷ Graph g ⇒ [a] → [b] → g (a, b)
Construct a torus graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", "\n", - "* The entire string prior to the kth match (i.e. the prefix)\n", - "* The kth match, followed by the remainder of the string\n", + "
\n",
+       "torus xs    []   == empty\n",
+       "torus []    ys   == empty\n",
+       "torus [x]   [y]  == edge (x,y) (x,y)\n",
+       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
+       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
+       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
+       "
\n", + "
\n", + "zipExactMay ∷ [a] → [b] → Maybe [(a, b)]
\n" + ], + "text/plain": [ + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "Examples:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "The needle parameter may not be empty. \n", - "breakOnAll :: Text -> Text -> [(Text, Text)]\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text-Lazy.html#v:breakOnAll\n", - "O(n+m) Find all non-overlapping instances of needle in haystack. Each element of the returned list consists of a pair:\n", + "zip is right-lazy:\n", "\n", - "* The entire string prior to the kth match (i.e. the prefix)\n", - "* The kth match, followed by the remainder of the string\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "Examples:\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/Data-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "> breakOnAll \"::\" \"\"\n", - "> ==> []\n", - "> breakOnAll \"/\" \"a/b/c/\"\n", - "> ==> [(\"a\", \"/b/c/\"), (\"a/b\", \"/c/\"), (\"a/b/c\", \"/\")]\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "This function is strict in its first argument, and lazy in its second.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "The needle parameter may not be empty. \n", - "genLNodes :: Enum a => a -> Int -> [LNode a]\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Example.html#v:genLNodes\n", - "generate list of labeled nodes \n", - "gmapAccumT :: Data d => (forall e. Data e => a -> e -> (a, e)) -> a -> d -> (a, d)\n", - "URL: http://hackage.haskell.org/packages/archive/syb/latest/doc/html/Data-Generics-Twins.html#v:gmapAccumT\n", - "gmapT with accumulation \n", - "threadList :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList\n", + "zip is right-lazy:\n", "\n", - "threadList' :: (Collect r c) -> (Split t i r) -> [i] -> t -> (c, t)\n", - "URL: http://hackage.haskell.org/packages/archive/fgl/latest/doc/html/Data-Graph-Inductive-Internal-Thread.html#v:threadList-39-\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", - "mapAccumR :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Lazy-Char8.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumL\n", - "The mapAccumL function behaves like a combination of map and foldl; it applies a function to each element of a ByteString, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list. \n", - "mapAccumR :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString-Char8.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and foldr; it applies a function to each element of a ByteString, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new ByteString. \n", - "mapAccumL :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumL\n", - "O(n) Like a combination of map and foldl'. Applies a function to each element of a Text, passing an accumulating parameter from left to right, and returns a final Text. Performs replacement on invalid scalar values. \n", - "mapAccumR :: (a -> Char -> (a, Char)) -> a -> Text -> (a, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:mapAccumR\n", - "The mapAccumR function behaves like a combination of map and a strict foldr; it applies a function to each element of a Text, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new Text. Performs replacement on invalid scalar values. \n", - "execRWS :: RWS r w s a -> r -> s -> (s, w)\n", - "URL: http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html#v:execRWS\n", - "Evaluate a computation with the given initial state and environment, returning the final state and output, discarding the final value. \n", - "breakSubstring :: ByteString -> ByteString -> (ByteString, ByteString)\n", - "URL: http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html#v:breakSubstring\n", - "otherwise -> Just (length x) \n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/GHC-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "For example, to tokenise a string, dropping delimiters:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> tokenise x y = h (:) if null t then [] else tokenise x (drop (length x) t)\n", - "> \n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "To skip to the first occurence of a string:\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "> snd (breakSubstring x y)\n", + "zip is right-lazy:\n", "\n", - "To take the parts of a string before a delimiter:\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "> fst (breakSubstring x y) \n", - "breakOn :: Text -> Text -> (Text, Text)\n", - "URL: http://hackage.haskell.org/packages/archive/text/latest/doc/html/Data-Text.html#v:breakOn\n", - "O(n+m) Find the first instance of needle (which must be non-null) in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match.\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base/docs/GHC-OldList.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", "\n", - "Examples:\n", + "
\n",
+       "zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')]\n",
+       "
\n", "\n", - "> breakOn \"::\" \"a::b::c\" ==> (\"a\", \"::b::c\")\n", - "> breakOn \"/\" \"foobar\" ==> (\"foobar\", \"\")\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded:\n", "\n", - "Laws:\n", + "
\n",
+       "zip [1] ['a', 'b'] = [(1, 'a')]\n",
+       "zip [1, 2] ['a'] = [(1, 'a')]\n",
+       "
\n", "\n", - "> append prefix match == haystack\n", - "> \n", + "zip is right-lazy:\n", "\n", - "If you need to break a string by a substring repeatedly (e.g. you want to break on every instance of a substring), use breakOnAll instead, as it has lower startup overhead.\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "zip _|_ [] = _|_\n",
+       "
\n", "\n", - "In (unlikely) bad cases, this function's time complexity degrades towards O(n*m)." + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/hspec/docs/Test-Hspec-Discover.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/Cabal/docs/Distribution-Compat-Prelude-Internal.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zipExact :: Partial => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExact\n", + "
\n",
+       "zipExact xs ys =\n",
+       "| length xs == length ys = zip xs ys\n",
+       "| otherwise              = error \"some message\"\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/base-compat/docs/Prelude-Compat.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/protolude/docs/Protolude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/numeric-prelude/docs/NumericPrelude-Base.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-List.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/fay-base/docs/Prelude.html#v:zip\n", + "\n", + "(+*+) :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:-43--42--43-\n", + "Slightly unfair 2-way Cartesian product: given two (possibly infinite)\n", + "lists, produce a single list such that whenever v and\n", + "w have finite indices in the input lists, (v,w) has\n", + "finite index in the output list. Lower indices occur as the\n", + "fst part of the tuple more frequently, but not exponentially\n", + "so.\n", + "\n", + "unfairCartesianProduct :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universe-base/docs/Data-Universe-Helpers.html#v:unfairCartesianProduct\n", + "Very unfair 2-way Cartesian product: same guarantee as the slightly\n", + "unfair one, except that lower indices may occur as the fst\n", + "part of the tuple exponentially more frequently. This mainly exists as\n", + "a specification to test against.\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/llvm-hs-pure/docs/LLVM-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/universum/docs/Universum-List-Reexport.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/haxl/docs/Haxl-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/prelude-compat/docs/Data-List2010.html#v:zip\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/prelude-compat/docs/Prelude2010.html#v:zip\n", + "\n", + "zip :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq-ListSeq.html#v:zip\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/LambdaHack/docs/Game-LambdaHack-Common-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/intro/docs/Intro.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/yesod-paginator/docs/Yesod-Paginator-Prelude.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/hledger-web/docs/Hledger-Web-Import.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zip :: () => [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/relude/docs/Relude-List-Reexport.html#v:zip\n", + "zip takes two lists and returns a list of corresponding pairs.\n", + "If one input list is short, excess elements of the longer list are\n", + "discarded.\n", + "\n", + "zip is right-lazy:\n", + "\n", + "
\n",
+       "zip [] _|_ = []\n",
+       "
\n", + "\n", + "zipLazy :: [a] -> [b] -> [(a, b)]\n", + "URL: https://hackage.haskell.org/package/ghc/docs/Util.html#v:zipLazy\n", + "zipLazy is a kind of zip that is lazy in the second list\n", + "(observe the ~)\n", + "\n", + "concurrently :: MonadBaseControl IO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted.html#v:concurrently\n", + "Generalized version of concurrently.\n", + "\n", + "concurrently :: forall m a b . (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/lifted-async/docs/Control-Concurrent-Async-Lifted-Safe.html#v:concurrently\n", + "Generalized version of concurrently.\n", + "\n", + "pairADefault :: Applicative f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:pairADefault\n", + "Default '>*< implementation for non-invertible\n", + "Applicatives.\n", + "\n", + "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/vector/docs/Data-Vector-Generic.html#v:zip\n", + "O(min(m,n)) Zip two vectors\n", + "\n", + "pair :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/statistics/docs/Statistics-Sample.html#v:pair\n", + "Pair two samples. It's like zip but requires that both samples\n", + "have equal size.\n", + "\n", + "zip :: (Vector v a, Vector v b, Vector v (a, b)) => v a -> v b -> v (a, b)\n", + "URL: https://hackage.haskell.org/package/rio/docs/RIO-Vector.html#v:zip\n", + "O(min(m,n)) Zip two vectors\n", + "\n", + "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/unliftio/docs/UnliftIO-Async.html#v:concurrently\n", + "Unlifted concurrently.\n", + "\n", + "concurrently :: MonadUnliftIO m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/yesod-websockets/docs/Yesod-WebSockets.html#v:concurrently\n", + "Unlifted concurrently.\n", + "\n", + "zip :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonAPI/docs/Data-Edison-Seq.html#v:zip\n", + "Combine two sequences into a sequence of pairs. If the sequences are\n", + "different lengths, the excess elements of the longer sequence is\n", + "discarded.\n", + "\n", + "
\n",
+       "zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>\n",
+       "where j = min {n,m}\n",
+       "
\n", + "\n", + "Axioms:\n", + "\n", + "
    \n", + "
  • zip xs ys = zipWith (,) xs ys
  • \n", + "
\n", + "\n", + "This function is always unambiguous.\n", + "\n", + "Default running time: O( min( n1, n2 ) )\n", + "\n", + "zipUsingLview :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLview\n", + "\n", + "zipUsingLists :: Sequence s => s a -> s b -> s (a, b)\n", + "URL: https://hackage.haskell.org/package/EdisonCore/docs/Data-Edison-Seq-Defaults.html#v:zipUsingLists\n", + "\n", + "concurrently :: MonadConc m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/concurrency/docs/Control-Concurrent-Classy-Async.html#v:concurrently\n", + "Run two MonadConc actions concurrently, and return both\n", + "results. If either action throws an exception at any time, then the\n", + "other action is cancelled, and the exception is re-thrown by\n", + "concurrently.\n", + "\n", + "
\n",
+       "concurrently left right =\n",
+       "withAsync left $ \\a ->\n",
+       "withAsync right $ \\b ->\n",
+       "waitBoth a b\n",
+       "
\n", + "\n", + "mzipRep :: Representable f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/adjunctions/docs/Data-Functor-Rep.html#v:mzipRep\n", + "\n", + "box :: Graph g => g a -> g b -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:box\n", + "Compute the Cartesian product of graphs. Complexity: O(s1 *\n", + "s2) time, memory and size, where s1 and s2 are the\n", + "sizes of the given graphs.\n", + "\n", + "
\n",
+       "box (path [0,1]) (path \"ab\") == edges [ ((0,'a'), (0,'b'))\n",
+       ", ((0,'a'), (1,'a'))\n",
+       ", ((0,'b'), (1,'b'))\n",
+       ", ((1,'a'), (1,'b')) ]\n",
+       "
\n", + "\n", + "Up to an isomorphism between the resulting vertex types, this\n", + "operation is commutative, associative,\n", + "distributes over overlay, has singleton graphs as\n", + "identities and empty as the annihilating zero.\n", + "Below ~~ stands for the equality up to an isomorphism, e.g.\n", + "(x, ()) ~~ x.\n", + "\n", + "
\n",
+       "box x y               ~~ box y x\n",
+       "box x (box y z)       ~~ box (box x y) z\n",
+       "box x (overlay y z)   == overlay (box x y) (box x z)\n",
+       "box x (vertex ())     ~~ x\n",
+       "box x empty           ~~ empty\n",
+       "vertexCount (box x y) == vertexCount x * vertexCount y\n",
+       "edgeCount   (box x y) <= vertexCount x * edgeCount y + edgeCount x * vertexCount y\n",
+       "
\n", + "\n", + "divided :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/contravariant/docs/Data-Functor-Contravariant-Divisible.html#v:divided\n", + "
\n",
+       "divided = divide id\n",
+       "
\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/dhall/docs/Dhall.html#v:-62--42--60-\n", + "The RecordInputType divisible (contravariant) functor allows\n", + "you to build an InputType injector for a Dhall record.\n", + "\n", + "For example, let's take the following Haskell data type:\n", + "\n", + "
\n",
+       "data Project = Project\n",
+       "{ projectName :: Text\n",
+       ", projectDescription :: Text\n",
+       ", projectStars :: Natural\n",
+       "}\n",
+       "
\n", + "\n", + "And assume that we have the following Dhall record that we would like\n", + "to parse as a Project:\n", + "\n", + "
\n",
+       "{ name =\n",
+       "\"dhall-haskell\"\n",
+       ", description =\n",
+       "\"A configuration language guaranteed to terminate\"\n",
+       ", stars =\n",
+       "289\n",
+       "}\n",
+       "
\n", + "\n", + "Our injector has type InputType Project, but we can't\n", + "build that out of any smaller injectors, as InputTypes cannot\n", + "be combined (they are only Contravariants). However, we can use\n", + "an InputRecordType to build an InputType for\n", + "Project:\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputFieldWith \"name\" inject\n",
+       ">*< inputFieldWith \"description\" inject\n",
+       ">*< inputFieldWith \"stars\" inject\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Or, since we are simply using the Inject instance to inject\n", + "each field, we could write\n", + "\n", + "
\n",
+       "injectProject :: InputType Project\n",
+       "injectProject =\n",
+       "inputRecord\n",
+       "(  adapt >$< inputField \"name\"\n",
+       ">*< inputField \"description\"\n",
+       ">*< inputField \"stars\"\n",
+       ")\n",
+       "where\n",
+       "adapt (Project{..}) = (projectName, (projectDescription, projectStars))\n",
+       "
\n", + "\n", + "Infix divided\n", + "\n", + "divided :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:divided\n", + "
\n",
+       "divided = divide id\n",
+       "
\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:-62--42--60-\n", + "An alias to divided.\n", + "\n", + "(>*<) :: Divisible f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras.html#v:-62--42--60-\n", + "An alias to divided.\n", + "\n", + "contrazip2 :: Divisible f => f a1 -> f a2 -> f (a1, a2)\n", + "URL: https://hackage.haskell.org/package/rebase/docs/Rebase-Prelude.html#v:contrazip2\n", + "\n", + "contrazip2 :: forall f a1 a2 . Divisible f => f a1 -> f a2 -> f (a1, a2)\n", + "URL: https://hackage.haskell.org/package/contravariant-extras/docs/Contravariant-Extras-Contrazip.html#v:contrazip2\n", + "\n", + "pair :: Sized f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/size-based/docs/Control-Sized.html#v:pair\n", + "Default: pair a b = (,) $ a * b.\n", + "\n", + "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/bytestring/docs/Data-ByteString-Builder-Prim.html#v:-62--42--60-\n", + "A pairing/concatenation operator for builder primitives, both bounded\n", + "and fixed size.\n", + "\n", + "For example,\n", + "\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = \"xy\"\n",
+       "
\n", + "\n", + "We can combine multiple primitives using >*< multiple\n", + "times.\n", + "\n", + "
\n",
+       "toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = \"xyz\"\n",
+       "
\n", + "\n", + "(>*<) :: Monoidal f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/invertible/docs/Control-Invertible-Monoidal.html#v:-62--42--60-\n", + "Merge two functors into a tuple, analogous to liftA2\n", + "(,). (Sometimes known as **.)\n", + "\n", + "zip :: List l => l a -> l b -> l (a, b)\n", + "URL: https://hackage.haskell.org/package/List/docs/Data-List-Class.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/classy-prelude/docs/ClassyPrelude.html#v:zip\n", + "\n", + "zip :: (Zip f) => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/non-empty/docs/Data-NonEmpty-Class.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/keys/docs/Data-Key.html#v:zip\n", + "\n", + "zip :: Zip f => f a -> f b -> f (a, b)\n", + "URL: https://hackage.haskell.org/package/chunked-data/docs/Data-ChunkedZip.html#v:zip\n", + "\n", + "mzip :: MonadZip m => m a -> m b -> m (a, b)\n", + "URL: https://hackage.haskell.org/package/base/docs/Control-Monad-Zip.html#v:mzip\n", + "\n", + "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:projectZip\n", + "Zipping projections.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Arrow.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:projectZip\n", + "Zipping projections.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-query/docs/Database-Relational-Projectable.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)\n", + "URL: https://hackage.haskell.org/package/relational-record/docs/Database-Relational-Documentation.html#v:-62--60-\n", + "Binary operator the same as projectZip.\n", + "\n", + "biunfold :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfold\n", + "Given a way to generate elements, return a way to generate structures\n", + "containing those elements.\n", + "\n", + "biunfoldBF :: (Biunfoldable t, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable/docs/Data-Biunfoldable.html#v:biunfoldBF\n", + "Breadth-first unfold, which orders the result by the number of\n", + "choose calls.\n", + "\n", + "deserializeWith2 :: (Serial2 f, MonadGet m) => m a -> m b -> m (f a b)\n", + "URL: https://hackage.haskell.org/package/bytes/docs/Data-Bytes-Serial.html#v:deserializeWith2\n", + "\n", + "biunfoldRestrict :: (BiunfoldableR predA predB t, predA a, predB b, Unfolder f) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrict\n", + "\n", + "biunfoldRestrictBF :: (BiunfoldableR p q t, Unfolder f, p a, q b) => f a -> f b -> f (t a b)\n", + "URL: https://hackage.haskell.org/package/unfoldable-restricted/docs/Data-Unfoldable-Restricted.html#v:biunfoldRestrictBF\n", + "\n", + "mesh :: Graph g => [a] -> [b] -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:mesh\n", + "Construct a mesh graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", + "\n", + "
\n",
+       "mesh xs     []   == empty\n",
+       "mesh []     ys   == empty\n",
+       "mesh [x]    [y]  == vertex (x, y)\n",
+       "mesh xs     ys   == box (path xs) (path ys)\n",
+       "mesh [1..3] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(2,'b')), ((2,'a'),(2,'b'))\n",
+       ", ((2,'a'),(3,'a')), ((2,'b'),(3,'b')), ((3,'a'),(3,'b')) ]\n",
+       "
\n", + "\n", + "torus :: Graph g => [a] -> [b] -> g (a, b)\n", + "URL: https://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-HigherKinded-Class.html#v:torus\n", + "Construct a torus graph from two lists of vertices. Complexity:\n", + "O(L1 * L2) time, memory and size, where L1 and L2\n", + "are the lengths of the given lists.\n", + "\n", + "
\n",
+       "torus xs    []   == empty\n",
+       "torus []    ys   == empty\n",
+       "torus [x]   [y]  == edge (x,y) (x,y)\n",
+       "torus xs    ys   == box (circuit xs) (circuit ys)\n",
+       "torus [1,2] \"ab\" == edges [ ((1,'a'),(1,'b')), ((1,'a'),(2,'a')), ((1,'b'),(1,'a')), ((1,'b'),(2,'b'))\n",
+       ", ((2,'a'),(1,'a')), ((2,'a'),(2,'b')), ((2,'b'),(1,'b')), ((2,'b'),(2,'a')) ]\n",
+       "
\n", + "\n", + "zipExactMay :: [a] -> [b] -> Maybe [(a, b)]\n", + "URL: https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExactMay" ] }, "metadata": {}, @@ -2236,10 +3202,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If you need a refresher on all of the options, you can just use `:help`:" ] @@ -2247,11 +3210,7 @@ { "cell_type": "code", "execution_count": 26, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2288,10 +3247,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "All of the code you normally put into IHaskell is (like in GHCi) interpreted. However, sometimes you've perfected a function, and now need it to run faster. In that case, you can go ahead and define a module in a single cell. As long as your module has a module header along the lines of `module Name where`, IHaskell will recognize it as a module. It will create the file `A/B.hs`, compile it, and load it. " ] @@ -2299,11 +3255,7 @@ { "cell_type": "code", "execution_count": 27, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "-- If your code isn't running fast enough, you can just put it into a module.\n", @@ -2316,10 +3268,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Note that the module is by default imported unqualified, as though you had typed `import A.B`." ] @@ -2327,11 +3276,7 @@ { "cell_type": "code", "execution_count": 28, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2360,10 +3305,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Note that since a new module is imported, all previous bound identifiers are now unbound. For instance, we no longer have access to the `f` function from before:" ] @@ -2371,11 +3313,7 @@ { "cell_type": "code", "execution_count": 29, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2477,10 +3415,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "However, if you re-import this module with another import statement, the original implicit import goes away." ] @@ -2488,11 +3423,7 @@ { "cell_type": "code", "execution_count": 30, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2522,10 +3453,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Thanks!\n", "---\n", @@ -2549,7 +3477,8 @@ "codemirror_mode": "ihaskell", "file_extension": ".hs", "name": "haskell", - "version": "8.0.2" + "pygments_lexer": "Haskell", + "version": "8.4.3" }, "latex_envs": { "bibliofile": "biblio.bib", @@ -2570,5 +3499,5 @@ } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 }