{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "IHaskell Notebook Test 1\n", "===\n", "\n", "Acceptance test for IHaskell, based on `notebooks/IHaskell.ipynb`" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "\"Hello, World!\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- First of all, we can evaluate simple expressions.\n", "3 + 5\n", "\"Hello, \" ++ \"World!\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test the `itN` variable" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"Hello, World!\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "it1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test multi-line expressions" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"Hello, World!\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- Unlike in GHCi, we can have multi-line expressions.\n", "concat [\n", " \"Hello\",\n", " \", \",\n", " \"World!\"\n", " ] :: String" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test top-level declaration" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "100" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "12" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "thing :: String -> Int -> Int\n", "thing \"no\" _ = 100\n", "thing str int = int + length str\n", "\n", "thing \"no\" 10\n", "thing \"ah\" 10" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test IO" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"What's going on?\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print \"What's going on?\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test the `:extension` directive" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "ename": "", "evalue": "", "output_type": "error", "traceback": [ ":1:1: error:\n • ‘Thing’ has no constructors (EmptyDataDecls permits this)\n • In the data declaration for ‘Thing’" ] } ], "source": [ "-- We can disable extensions.\n", ":ext NoEmptyDataDecls\n", "data Thing" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "-- And enable extensions.\n", ":ext EmptyDataDecls\n", "data Thing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test Data declarations" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[A \"Hello\",B 10]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- Various data declarations work fine.\n", "data One\n", " = A String\n", " | B Int\n", " deriving Show\n", "\n", "print [A \"Hello\", B 10]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test `:type`" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "3 + 3 :: forall {a}. Num a => a" ], "text/plain": [ "3 + 3 :: forall {a}. Num a => a" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- We can look at types like in GHCi.\n", ":ty 3 + 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test `:info`" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
type Integral :: * -> Constraint
\n", "class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a, a)
divMod :: a -> a -> (a, a)
toInteger :: a -> Integer
{-# MINIMAL quotRem, toInteger #-}
\t
-- Defined in ‘GHC.Real’
\n", "instance Integral Int -- Defined in ‘GHC.Real’
\n", "instance Integral Integer -- Defined in ‘GHC.Real’
\n", "instance Integral Word -- Defined in ‘GHC.Real’
" ], "text/plain": [ "type Integral :: * -> Constraint\n", "class (Real a, Enum a) => Integral a where\n", " quot :: a -> a -> a\n", " rem :: a -> a -> a\n", " div :: a -> a -> a\n", " mod :: a -> a -> a\n", " quotRem :: a -> a -> (a, a)\n", " divMod :: a -> a -> (a, a)\n", " toInteger :: a -> Integer\n", " {-# MINIMAL quotRem, toInteger #-}\n", " \t-- Defined in ‘GHC.Real’\n", "instance Integral Int -- Defined in ‘GHC.Real’\n", "instance Integral Integer -- Defined in ‘GHC.Real’\n", "instance Integral Word -- Defined in ‘GHC.Real’" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- What is the Integral typeclass?\n", ":info Integral" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test `IHaskellDisplay`" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Look!
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Look!
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Look!
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import IHaskell.Display\n", "\n", "data Color = Red | Green | Blue\n", "\n", "instance IHaskellDisplay Color where\n", " display color = return $ Display [html code]\n", " where\n", " code = concat [\"
Look!
\"]\n", " css Red = \"red\"\n", " css Blue = \"blue\"\n", " css Green = \"green\"\n", "\n", "Red\n", "Green\n", "Blue" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test `hlint` " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Redundant $
Found:
f $ 3
Why Not:
f 3
" ], "text/plain": [ "Line 7: Redundant $\n", "Found:\n", "f $ 3\n", "Why not:\n", "f 3" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "4" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- There is also hlint integration enabled by default.\n", "-- If you write sketchy code, it will tell you:\n", "f :: Int -> Int\n", "f x = x + 1\n", "\n", "-- Most warnings are orange...\n", "f $ 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test `:help`" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "The following commands are available:\n", " :extension - Enable a GHC extension.\n", " :extension No - Disable a GHC extension.\n", " :type - Print expression type.\n", " :info - Print all info for a name.\n", " :hoogle - Search for a query on Hoogle.\n", " :doc - Get documentation for an identifier via Hoogle.\n", " :set -XFlag -Wall - Set an option (like ghci).\n", " :option - Set an option.\n", " :option no- - Unset an option.\n", " :?, :help - Show this help text.\n", " :sprint - Print a value without forcing evaluation.\n", "\n", "Any prefix of the commands will also suffice, e.g. use :ty for :type.\n", "\n", "Options:\n", " lint – enable or disable linting.\n", " svg – use svg output (cannot be resized).\n", " show-types – show types of all bound names\n", " show-errors – display Show instance missing errors normally.\n", " pager – use the pager to display results of :info, :doc, :hoogle, etc." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ ":help" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test `:sprint`" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'d'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "x = 'a' : 'b' : 'c' : 'd' : _\n", "" ], "text/plain": [ "x = 'a' : 'b' : 'c' : 'd' : _" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = ['a'..'z']\n", "x !! 3\n", ":sprint x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test `module Name where`\n", "\n", "IHaskell will create the file `A/B.hs`, compile it, and load it. " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "-- If your code isn't running fast enough, you can just put it into a module.\n", "module A.B where\n", "\n", "fib 0 = 1\n", "fib 1 = 1\n", "fib n = fib (n-1) + fib (n-2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test module import\n", "\n", "Note that the module is by default imported unqualified, as though you had typed `import A.B`." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10946" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "10946" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- The module is automatically imported unqualified.\n", "print $ A.B.fib 20\n", "print $ fib 20" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test module unbind identifiers\n", "\n", "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:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "ename": "", "evalue": "", "output_type": "error", "traceback": [ ":1:1: error: Variable not in scope: f :: String -> t" ] } ], "source": [ "f \"hello\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test module re-import\n", "\n", "re-import this module with another import statement, the original implicit import goes away." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10946" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "10946" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import qualified A.B as Fib\n", "\n", "Fib.fib 20\n", "fib 20" ] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Haskell", "language": "haskell", "name": "haskell" }, "language_info": { "codemirror_mode": "ihaskell", "file_extension": ".hs", "mimetype": "text/x-haskell", "name": "haskell", "pygments_lexer": "Haskell", "version": "9.4.5" }, "latex_envs": { "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 0 }, "nav_menu": {}, "toc": { "navigate_menu": true, "number_sections": true, "sideBar": true, "threshold": 6, "toc_cell": false, "toc_section_display": "block", "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }