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

do
  return 3


Redundant $
Found:
f \$ 3
Why Not:
f 3
Redundant do
Found:
do return 3
Why Not:
return 3
4
3

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 3


<interactive>:1:1: error: Variable not in scope: f :: Integer -> 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