explicitly typed exceptions for haskell (padl'10)

Upload: jose-iborra

Post on 30-May-2018

224 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    1/101

    Explicitly Typed Exceptionsfor Haskell (2011?)

    Jos IborraUniversidad Politcnica de Valencia

    PADL 2010

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    2/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Compare this code in a programming language:

    with the equivalent Haskell code

    Both can fail with an exception

    but only one compiler detects it

    publicstaticvoid main(String[] args) { String filepath = args[1]; Reader f = new FileReader(filepath);

    doSomethingWith(f); }

    main = dofilepath

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    3/101

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    4/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Checked Exceptions

    Detected and enforced by the compiler

    Usually explicit: possible exceptions appear on the type

    automatically documented

    the programmer has no need to think whatexceptions can be raised inside this block ?

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    5/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Checked Exceptions

    Detected and enforced by the compiler

    Usually explicit: possible exceptions appear on the type

    automatically documented

    the programmer has no need to think whatexceptions can be raised inside this block ?

    Checked exceptions are not always a goodthing

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    6/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    To check or not to check ?

    I used to think that checked exceptions were reallygreat - Bruce Eckel*

    I completely agree that checked exceptionsare a wonderful feature. Its just that existing

    implementations are notAnders Heljsberg*

    * - http://www.artima.com/intv/handcuffs.html

    Wednesday, January 20, 2010

    http://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.html
  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    7/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Exceptions in Haskell

    Extensible Hierarchical Explicit Checked Traced

    Haskell 98 (IO) Limited

    GHC*(IO) Yes Yes

    Either/ErrorTmonad

    Yesbut not

    composableYes Yes

    Yesbut wrongsemantics

    EMmonad Yes Yes Yes Yes Yes!

    GHC* -An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    8/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    eval:: Expr -> Double

    eval (Val x) = xeval (Add e1 e2) = eval e1 + eval e2

    eval (Div e1 e2) = eval e1 / eval e2

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    9/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    eval:: Expr -> Double

    eval (Val x) = xeval (Add e1 e2) = eval e1 + eval e2

    eval (Div e1 e2) = caseeval e2 of

    0 -> exception !

    x2 -> eval e1 / x2

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    10/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    eval:: Expr -> Either exception Double

    eval (Val x) = xeval (Add e1 e2) = eval e1 + eval e2

    eval (Div e1 e2) = caseeval e2 of

    0 -> Left exception

    x2 -> Right (eval e1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    11/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = x

    eval (Add e1 e2) = eval e1 + eval e2

    eval (Div e1 e2) = caseeval e2 of

    0 -> Left DivByZero

    x2 -> Right (eval e1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    12/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = x

    eval (Add e1 e2) = eval e1 + eval e2

    eval (Div e1 e2) = caseeval e2 of

    0 -> Left DivByZero

    x2 -> Right (eval e1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    13/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = eval e1 + eval e2

    eval (Div e1 e2) = caseeval e2 of

    0 -> Left DivByZero

    x2 -> Right (eval e1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    14/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Right x1 -> caseeval e2 of

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 of

    0 -> Left DivByZero

    x2 -> Right (eval e1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    15/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Right x1 -> caseeval e2 of

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 of

    Right 0 -> Left DivByZero

    Right x2 -> Right (eval e1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    16/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Right x1 -> caseeval e2 of

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 of

    Right 0 -> Left DivByZero

    Right x2 -> caseeval e1 ofRight x1 -> Right(x1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    17/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Left e -> Left e

    Right x1 -> caseeval e2 of

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 of

    Right 0 -> Left DivByZeroRight x2 -> caseeval e1 of

    Right x1 -> Right(x1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    18/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Left e -> Left e

    Right x1 -> caseeval e2 of

    Left e -> Left e

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 ofRight 0 -> Left DivByZero

    Right x2 -> caseeval e1 of

    Right x1 -> Right(x1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

    E li i l T d E i f H k ll PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    19/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Left e -> Left e

    Right x1 -> caseeval e2 of

    Left e -> Left e

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 ofLeft e -> Left e

    Right 0 -> Left DivByZero

    Right x2 -> caseeval e1 of

    Right x1 -> Right(x1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

    E li i l T d E i f H k ll PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    20/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleeval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Left e -> Left e

    Right x1 -> caseeval e2 of

    Left e -> Left e

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 ofLeft e -> Left e

    Right 0 -> Left DivByZero

    Right x2 -> caseeval e1 of

    Left e -> Left e

    Right x1 -> Right(x1 / x2)

    data Either a b = Left a | Right b

    Wednesday, January 20, 2010

    E li itl T d E ti f H k ll PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    21/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL10

    Universidad Politcnica de Valencia

    Error handling in Haskell

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Left e -> Left e

    Right x1 -> caseeval e2 ofLeft e -> Left e

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 of

    Left e -> Left e

    Right 0 -> Left DivByZero

    Right x2 -> caseeval e1 of

    Left e -> Left eRight x1 -> Right(x1 / x2)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    22/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL 10

    Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = Right x

    eval (Add e1 e2) = caseeval e1 of

    Left e -> Left e

    Right x1 -> caseeval e2 ofLeft e -> Left e

    Right x2 -> Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 of

    Left e -> Left e

    Right 0 -> Left DivByZero

    Right x2 -> caseeval e1 of

    Left e -> Left eRight x1 -> Right(x1 / x2)

    Left e >>= f = Left e

    Right x >>= f = f x

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    23/101

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    24/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL 10

    Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = Right x

    eval (Add e1 e2) = eval e1>>= \x1 -> eval e2 >>=\x2 ->

    Right(x1 + x2)

    eval (Div e1 e2) = caseeval e2 ofLeft e -> Left e

    Right 0 -> Left DivByZero

    Right x2 -> caseeval e1 of

    Left e -> Left e

    Right x1 -> Right(x1 / x2)

    Left e >>= f = Left e

    Right x >>= f = f x

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    25/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL 10

    Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = Right x

    eval (Add e1 e2) = eval e1>>= \x1 -> eval e2 >>=\x2 ->

    Right(x1 + x2)

    eval (Div e1 e2) = eval e2>>= \x2 -> casex2 of

    0 -> Left DivByZero

    x2 -> caseeval e1 of

    Left e -> Left e

    Right x1 -> Right(x1 / x2)

    Left e >>= f = Left e

    Right x >>= f = f x

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    26/101

    Jos Iborra

    Explicitly Typed Exceptions for Haskell PADL 10

    Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = Right x

    eval (Add e1 e2) = eval e1>>= \x1 -> eval e2 >>=\x2 ->

    Right(x1 + x2)

    eval (Div e1 e2) = eval e2>>= \x2 -> casex2 of

    0 -> Left DivByZero

    x2 -> eval e1>>= \x1 -> Right(x1 / x2)

    Left e >>= f = Left e

    Right x >>= f = f x

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    27/101

    Jos Iborra

    p y yp p

    Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = Right x

    eval (Add e1 e2) = eval e1>>= \x1 -> eval e2 >>=\x2 ->

    Right(x1 + x2)

    eval (Div e1 e2) = eval e2>>= \x2 -> casex2 of

    0 -> Left DivByZero

    x2 -> eval e1>>= \x1 -> Right(x1 / x2)

    instance Error e => Monad (Either e) where

    Left e >>= f = Left eRight x >>= f = f x

    return = Right

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    28/101

    Jos Iborra

    p y yp p

    Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = eval e1>>= \x1 -> eval e2 >>=\x2 ->

    Right(x1 + x2)

    eval (Div e1 e2) = eval e2>>= \x2 -> case x2 of

    0 -> Left DivByZero

    x2 -> eval e1>>= \x1 -> Right(x1 / x2)

    instance Error e => Monad (Either e) where

    Left e >>= f = Left eRight x >>= f = f x

    return = Right

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    29/101

    Jos Iborra

    p y yp p

    Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = eval e1>>= \x1 -> eval e2 >>=\x2 ->

    return(x1 + x2)

    eval (Div e1 e2) = eval e2>>= \x2 -> case x2 of

    0 -> Left DivByZero

    x2 -> eval e1>>= \x1 -> Right(x1 / x2)

    instance Error e => Monad (Either e) where

    Left e >>= f = Left eRight x >>= f = f x

    return = Right

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    30/101

    Jos Iborra Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = eval e1>>= \x1 -> eval e2 >>=\x2 ->

    return(x1 + x2)

    eval (Div e1 e2) = eval e2>>= \x2 -> case x2 of

    0 -> Left DivByZero

    x2 -> eval e1>>= \x1 -> return(x1 / x2)

    instance Error e => Monad (Either e) where

    Left e >>= f = Left eRight x >>= f = f x

    return = Right

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    31/101

    Jos Iborra Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = do x1 = \x2 ->

    case x2 of

    0 -> Left DivByZero

    x2 -> eval e1>>= \x1 -> return(x1 / x2)

    instance Error e => Monad (Either e) whereLeft e >>= f = Left e

    Right x >>= f = f x

    return = Right

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    32/101

    Jos Iborra Universidad Politcnica de Valencia

    Error handling with monads

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = do x1 >= f = Left e

    Right x >>= f = f x

    return = Right

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    33/101

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    34/101

    Jos Iborra Universidad Politcnica de Valencia

    Error handling with monads

    catch (Right x) handler = Right x

    catch (Left e) handler = handler e

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = do x1

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    35/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = do x1

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    36/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    parse :: String -> Either ParseError Expr

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Double

    eval (Val x) = return x

    eval (Add e1 e2) = do x1

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    37/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    38/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    39/101

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    40/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    mapError :: (e -> e) -> Either e a -> Either e a

    mapError f (Left e) = Left (f e)

    mapError f (Right r) = Right r

    parse = mapError ParseE . parse

    eval = mapError EvalE . eval

    run :: String -> Either ParseOrDivError Double

    run str = do { e

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    41/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    mapError :: (e -> e) -> Either e a -> Either e a

    mapError f (Left e) = Left (f e)

    mapError f (Right r) = Right r

    parse = mapError ParseE . parse

    eval = mapError EvalE . eval

    run :: String -> Either ParseOrDivError Double

    run str = do { e

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    42/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    mapError :: (e -> e) -> Either e a -> Either e a

    mapError f (Left e) = Left (f e)

    mapError f (Right r) = Right r

    parse = mapError ParseE . parse

    eval = mapError EvalE . eval

    run :: String -> Either ParseOrDivError Double

    run str = do { e

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    43/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    run :: String -> Either ParseOrDivError Double

    run str = do { e

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    44/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    run :: String -> Either ParseOrDivError Double

    run str = do

    e

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    45/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    run :: String -> Either ParseOrDivError Double

    run str = do

    e return 0

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    46/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    run :: String -> Either ParseOrDivError Double

    run str = do

    e return 0

    Warning: Pattern match(es) are non-exhaustiveIn a case alternative:Patterns not matched:

    ParseE

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    47/101

    Jos Iborra Universidad Politcnica de Valencia

    The Either Monad User extensible Hierarchical Checked Explicit

    data Expr = Add Expr Expr | Div Expr Expr | Val Double

    data DivByZero = DivByZero deriving Show

    eval:: Expr -> Either DivByZero Doubleparse :: String -> Either ParseError Expr

    data ParseOrDivError = ParseE ParseError

    | EvalE DivByZero

    run :: String -> Either ParseOrDivError Double

    run str = do

    e return 0

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    48/101

    Jos Iborra Universidad Politcnica de Valencia

    A monad for Explicitly Typed Exceptions

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    49/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    50/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    51/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    52/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    53/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    54/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    55/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    56/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    57/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    catchC# = ... -- uses casting, slightly more involved

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    58/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    catchC# = ... -- uses casting, slightly more involved

    User extensible Hierarchical Checked Explicit

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    59/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    catchC# = ... -- uses casting, slightly more involved

    User extensible Hierarchical Checked Explicit

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    60/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    catchC# = ... -- uses casting, slightly more involved

    User extensible Hierarchical Checked Explicit

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    61/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    catchC# = ... -- uses casting, slightly more involved

    User extensible Hierarchical Checked Explicit

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    62/101

    Jos Iborra Universidad Politcnica de Valencia

    Fixing the composability problem

    Apply the extensible + hierarchical exceptions datatype ofMarlow*data SomeException = e. (Show e, Typeable e) => SomeException e

    class Exception e where

    fromException :: SomeException -> e

    toException :: e -> SomeException

    defining a new monad of non-explicit, composableexceptions

    newtype C# a = C# (Either SomeException a)

    deriving Monad -- C# is isomorphic to Either

    throwC# :: Exception e => e -> C# a

    throwC# = C# . Left . toException

    catchC# = ... -- uses casting, slightly more involved

    User extensible Hierarchical Checked Explicit

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    63/101

    Jos Iborra Universidad Politcnica de Valencia

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving (Show,Typeable)

    instance Exception DivByZero

    eval:: Expr -> C# Double

    eval (Val x) = return x

    eval (Add e1 e2) = do x1 C# Double

    run str = do { e

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    64/101

    Jos Iborra Universidad Politcnica de Valencia

    The Explicit Exceptions Monad

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    class Exception e=> Throws e l

    throwEM :: Throws e l => e -> EM l athrowEM = EM . Left . toException

    newtype EM l a = EM (Either SomeException a) deriving Monad

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    65/101

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    66/101

    Jos Iborra Universidad Politcnica de Valencia

    The Explicit Exceptions Monad

    Idea: the type of a computation includes the exceptions itmay throw.

    Establish a type-level relationship between a computationand every exception it may throw

    Encoded as a list of type class constraints

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    class Exception e=> Throws e l

    throwEM :: Throws e l => e -> EM l athrowEM = EM . Left . toException

    newtype EM l a = EM (Either SomeException a) deriving Monad

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    67/101

    Jos Iborra Universidad Politcnica de Valencia

    The Explicit Exceptions Monad

    Idea: the type of a computation includes the exceptions itmay throw.

    Establish a type-level relationship between a computationand every exception it may throw

    Encoded as a list of type class constraints

    *An extensible dynamically typed hierarchy of Exceptions - S. Marlow (2006)

    This is not the most

    general typeclass Exception e=> Throws e l

    throwEM :: Throws e l => e -> EM l athrowEM = EM . Left . toException

    newtype EM l a = EM (Either SomeException a) deriving Monad

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    68/101

    Jos Iborra Universidad Politcnica de Valencia

    data Expr = Add Expr Expr | Div Expr Expr | Val Doubledata DivByZero = DivByZero deriving (Show,Typeable)

    instance Exception DivByZero

    eval:: Throws DivByZero l => Expr -> EM l Double

    eval (Val x) = return x

    eval (Add e1 e2) = do x1 EM l Expr

    run :: (Throws DivByZero l, Throws ParseError l) =>

    String -> EM l Double

    run str = do { e

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    69/101

    Jos Iborra Universidad Politcnica de Valencia

    newtype EM l a = EM (Either SomeException a) deriving Monad

    EM a >>=EMk = EM (a >>=Either ...)

    returnEM = EM . returnEither

    throwEM :: Throws e l => e -> EM l athrowEM = EM . Left . toException --identical to throwC#, modulo the EM wrapper

    catchEM :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catchEM = ... -- identical to catchC#, modulo the EM wrapper

    runEM :: EM l x -> xrunEM (EM (Right x)) = x

    tryEM :: EM Any x -> Either SomeException xtryEM (EM x) = x

    private

    public

    The Explicit Exceptions Monad Kernel(a la Lightweight Dependent Types)*

    * - Lightweight static capabilities, Kiselyov & Shan, 2007

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    70/101

    Jos Iborra Universidad Politcnica de Valencia

    Reasoning about exceptions

    M, N = return H H pure| M >>= N| throw e| catch M (e N)| if H then M else N

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    71/101

    Jos Iborra Universidad Politcnica de Valencia

    Reasoning about exceptions

    |M| = m |N| = n

    |M >>= N| = m n

    |M| =m |N| = n

    |if H then M else N

    |=m n

    |throw e| = {e}|return H| = {} |M| = e2

    M, N = return H H pure| M >>= N| throw e| catch M (e N)| if H then M else N

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    72/101

    Jos Iborra Universidad Politcnica de Valencia

    Reasoning about exceptions

    |M| = m |N| = n

    |M >>= N| = m n

    |M| =m |N| = n

    |if H then M else N

    |=m n

    |throw e| = {e}|return H| = {} |M| = e2

    M, N = return H H pure| M >>= N| throw e| catch M (e N)| if H then M else N

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    73/101

    Jos Iborra Universidad Politcnica de Valencia

    Reasoning about exceptions

    |M| = m |N| = n

    |M >>= N| = m n

    |M| =m |N| = n

    |if H then M else N

    |=m n

    |throw e| = {e}|return H| = {} |M| = e2

    M, N = return H H pure| M >>= N| throw e| catch M (e N)| if H then M else N

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    74/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    75/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    This is not the mostgeneral type

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    76/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    C

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    77/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    I l C h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    78/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    (`catch` \ParseError -> ..) :: EM (Caught ParseError l2) a -> EM l2 a

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    I l C h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    79/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    (`catch` \ParseError -> ..) :: EM (Caught ParseError l2) a -> EM l2 a

    parse str :: Throws ParseError l1 => EM l1 Expr

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    80/101

    Explicitly Typed Exceptions for Haskell PADL10

    I l i C h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    81/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    (`catch` \ParseError -> ..) :: EM (Caught ParseError l2) a -> EM l2 a

    parse str :: Throws ParseError l1 => EM l1 Expr

    parse `catch` \ParseError... :: EM l2 Expr

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    I l i C h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    82/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    I l i C h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    83/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    I l i C h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    84/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    (`catch` \DivByZero -> ..) :: EM (Caught DivByZero l2) a -> EM l2 a

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    I l ti C t h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    85/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    (`catch` \DivByZero -> ..) :: EM (Caught DivByZero l2) a -> EM l2 a

    parse str :: Throws ParseError l1 => EM l1 Expr

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    86/101

    Explicitly Typed Exceptions for Haskell PADL10

    I l ti C t h

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    87/101

    Jos Iborra Universidad Politcnica de Valencia

    Implementing Catch

    catch :: Exception e => EM (Caught e l) a -> (e -> EM l a) -> EM l a

    catch = ... --omitted, as before

    dataCaught e linstanceThrows e (Caught e l)

    instance Throws e l => Throws e (Caught e1 l)

    parse :: Throws ParseError l => String -> EM l Expr

    run :: ... => String -> ...

    run str = do

    e ...

    eval e

    (`catch` \DivByZero -> ..) :: EM (Caught DivByZero l2) a -> EM l2 a

    parse str :: Throws ParseError l1 => EM l1 Expr

    parse `catch` \DivByZero... :: Throws ParseError l2 => EM l2 Expr

    |C| = c |H| = h

    |catch C (e H)| = (c \ {e}) h

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    R i EM t ti

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    88/101

    Jos Iborra Universidad Politcnica de Valencia

    Running EM computations

    Checked version demanding that no exceptions leak:

    runEM:: EM l a -> a

    runEM (EM (Right x)) = x

    :t parse some string

    :t runEM (parse some string)No instance for (Throws ParseError l)

    Possible fix:

    add an instance declaration for (Throws ParseError l)

    parse some string :: Throws ParseError l => EM l Expr

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    Running EM computations

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    89/101

    Jos Iborra Universidad Politcnica de Valencia

    Unchecked version accepting computations which mayraise any exception

    Running EM computations

    data Any

    instanceThrows e Any

    tryEM :: EM Any a -> Either SomeException a

    tryEM (EM x) = x

    :t tryEM (parse this)

    tryEM (parse this) :: Either SomeException Expr

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    90/101

    Explicitly Typed Exceptions for Haskell PADL10

    Running EM computations

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    91/101

    Jos Iborra Universidad Politcnica de Valencia

    Unchecked version accepting computations which mayraise any exception

    Running EM computations

    data Any

    instanceThrows e Any

    tryEM :: EM Any a -> Either SomeException a

    tryEM (EM x) = x

    :t tryEM (parse this)

    tryEM (parse this) :: Either SomeException Expr

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    92/101

    Explicitly Typed Exceptions for Haskell PADL10

    Running EM computations

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    93/101

    Jos Iborra Universidad Politcnica de Valencia

    Running EM computations

    Selectively turning exceptions into unchecked exceptions

    data OnlyUnchecked

    class Exception e => UncheckedException e

    instance UncheckedException e => Throws e OnlyUnchecked

    runEM :: EM OnlyUnchecked a -> a

    runEM (EM (Right x)) = xrunEM (EM (Left e)) = error (Unchecked exception: ++ show e)

    parse :: Throws ParseError l => String -> EM l Expr

    eval :: Throws DivByZero l => Expr -> EM l Double

    instance UncheckedException ParseError

    main :: String -> Double

    main str = runEM $ do

    e ...

    type flag

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    To check or not to check ?

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    94/101

    Jos Iborra Universidad Politcnica de Valencia

    To check or not to check ?

    I used to think that checked exceptions were reallygreat - Bruce Eckel*

    I completely agree that checked exceptionsare a wonderful feature. Its just that existing

    implementations are notAnders Heljsberg*

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    To check or not to check ?

    http://www.artima.com/intv/handcuffs.html
  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    95/101

    Jos Iborra Universidad Politcnica de Valencia

    To check or not to check ?

    I used to think that checked exceptions were reallygreat - Bruce Eckel*

    I completely agree that checked exceptionsare a wonderful feature. Itsjust that existing

    implementations are notAnders Heljsberg*

    * - Monads are like Burritos, Brent Yorgey

    Burritos* make great exception libraries -Jose Iborra

    Wednesday, January 20, 2010

    http://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.htmlhttp://www.artima.com/intv/handcuffs.html
  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    96/101

    Explicitly Typed Exceptions for Haskell PADL10

    Choice (of Monad)

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    97/101

    Jos Iborra Universidad Politcnica de Valencia

    ( )

    class Monad m => MonadFailure e m where

    failure :: e -> m a

    instanceMonadFailure e Maybe where failure _ = Nothing

    instance Error e => MonadFailure e Either where failure = Left

    instance Throws e l => MonadFailure e (EM l) where

    failure = EM . Left . toException

    run :: (MonadFailure DivByZero m, MonadFailure ParseError m) =>

    String -> m Double

    parse :: (MonadFailure ParseError m) => String -> m Expr

    eval :: (MonadFailure DivByZero m) => Expr -> m Double

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    Choice (of Monad)

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    98/101

    Jos Iborra Universidad Politcnica de Valencia

    class Monad m => MonadFailure e m where

    failure :: e -> m a

    instanceMonadFailure e Maybe where failure _ = Nothing

    instance Error e => MonadFailure e Either where failure = Left

    instance Throws e l => MonadFailure e (EM l) where

    failure = EM . Left . toException

    run :: (MonadFailure DivByZero m, MonadFailure ParseError m) =>

    String -> m Double

    run :: (Throws DivByZero l, Throws ParseError l) => String -> EM l Double

    parse :: (MonadFailure ParseError m) => String -> m Expr

    eval :: (MonadFailure DivByZero m) => Expr -> m Double

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    Choice (of Monad)

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    99/101

    Jos Iborra Universidad Politcnica de Valencia

    class Monad m => MonadFailure e m where

    failure :: e -> m a

    instanceMonadFailure e Maybe where failure _ = Nothing

    instance Error e => MonadFailure e Either where failure = Left

    instance Throws e l => MonadFailure e (EM l) where

    failure = EM . Left . toException

    run :: (MonadFailure DivByZero m, MonadFailure ParseError m) =>

    String -> m Double

    run :: String -> Maybe Double

    run :: (Throws DivByZero l, Throws ParseError l) => String -> EM l Double

    parse :: (MonadFailure ParseError m) => String -> m Expr

    eval :: (MonadFailure DivByZero m) => Expr -> m Double

    Wednesday, January 20, 2010

    Explicitly Typed Exceptions for Haskell PADL10

    Choice (of Monad)

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    100/101

    Jos Iborra Universidad Politcnica de Valencia

    class Monad m => MonadFailure e m where

    failure :: e -> m a

    instanceMonadFailure e Maybe where failure _ = Nothing

    instance Error e => MonadFailure e Either where failure = Left

    instance Throws e l => MonadFailure e (EM l) where

    failure = EM . Left . toException

    run :: (MonadFailure DivByZero m, MonadFailure ParseError m) =>

    String -> m Double

    run :: String -> Maybe Double

    run :: (Throws DivByZero l, Throws ParseError l) => String -> EM l Double

    run :: ...

    parse :: (MonadFailure ParseError m) => String -> m Expr

    eval :: (MonadFailure DivByZero m) => Expr -> m Double

    Wednesday, January 20, 2010

  • 8/14/2019 Explicitly Typed Exceptions for Haskell (PADL'10)

    101/101

    Thanks