IHaskell Notebook Test 1

Acceptance test for IHaskell, based on notebooks/IHaskell.ipynb

In [1]:
-- First of all, we can evaluate simple expressions.
3 + 5
"Hello, " ++ "World!"
8
"Hello, World!"

Test the itN variable

In [2]:
it1
"Hello, World!"

Test multi-line expressions

In [3]:
-- Unlike in GHCi, we can have multi-line expressions.
concat [
  "Hello",
  ", ",
  "World!"
  ] :: String
"Hello, World!"

Test top-level declaration

In [4]:
thing :: String -> Int -> Int
thing "no" _ = 100
thing str int = int + length str

thing "no" 10
thing "ah" 10
100
12

Test IO

In [5]:
print "What's going on?"
"What's going on?"

Test the :extension directive

In [6]:
-- We can disable extensions.
:ext NoEmptyDataDecls
data Thing
<interactive>:1:1: error:
    • ‘Thing’ has no constructors (EmptyDataDecls permits this)
    • In the data declaration for ‘Thing’
In [7]:
-- And enable extensions.
:ext EmptyDataDecls
data Thing

Test Data declarations

In [8]:
-- Various data declarations work fine.
data One
     = A String
     | B Int
     deriving Show

print [A "Hello", B 10]
[A "Hello",B 10]

Test :type

In [9]:
-- We can look at types like in GHCi.
:ty 3 + 3
3 + 3 :: forall a. Num a => a

Test :info

In [10]:
:opt no-pager
In [11]:
-- What is the Integral typeclass?
:info Integral

Test IHaskellDisplay

In [12]:
import IHaskell.Display

data Color = Red | Green | Blue

instance IHaskellDisplay Color where
  display color = return $ Display [html code]
    where
      code = concat ["<div style='font-weight: bold; color:"
                    , css color
                    , "'>Look!</div>"]
      css Red   = "red"
      css Blue  = "blue"
      css Green = "green"

Red
Green
Blue
Look!
Look!
Look!

Test hlint

In [13]:
-- There is also hlint integration enabled by default.
-- If you write sketchy code, it will tell you:
f :: Int -> Int
f x = x + 1

-- Most warnings are orange...
f $ 3
Redundant $
Found:
f $ 3
Why Not:
f 3
4

Test :help

In [14]:
:help
The following commands are available:
    :extension <Extension>    -  Enable a GHC extension.
    :extension No<Extension>  -  Disable a GHC extension.
    :type <expression>        -  Print expression type.
    :info <name>              -  Print all info for a name.
    :hoogle <query>           -  Search for a query on Hoogle.
    :doc <ident>              -  Get documentation for an identifier via Hoogle.
    :set -XFlag -Wall         -  Set an option (like ghci).
    :option <opt>             -  Set an option.
    :option no-<opt>          -  Unset an option.
    :?, :help                 -  Show this help text.
    :sprint <value>           -  Print a value without forcing evaluation.

Any prefix of the commands will also suffice, e.g. use :ty for :type.

Options:
  lint        – enable or disable linting.
  svg         – use svg output (cannot be resized).
  show-types  – show types of all bound names
  show-errors – display Show instance missing errors normally.
  pager       – use the pager to display results of :info, :doc, :hoogle, etc.

Test :sprint

In [15]:
x = ['a'..'z']
x !! 3
:sprint x
'd'
x = 'a' : 'b' : 'c' : 'd' : _

Test module Name where

IHaskell will create the file A/B.hs, compile it, and load it.

In [16]:
-- If your code isn't running fast enough, you can just put it into a module.
module A.B where

fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

Test module import

Note that the module is by default imported unqualified, as though you had typed import A.B.

In [17]:
-- The module is automatically imported unqualified.
print $ A.B.fib 20
print $ fib 20
10946
10946

Test module unbind identifiers

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:

In [18]:
f "hello"
<interactive>:1:1: error: Variable not in scope: f :: String -> t

Test module re-import

re-import this module with another import statement, the original implicit import goes away.

In [19]:
import qualified A.B as Fib

Fib.fib 20
fib 20
10946
10946