Grab bag of interesting stuff
Download
1 / 20

Grab Bag of Interesting Stuff - PowerPoint PPT Presentation


  • 58 Views
  • Uploaded on

Grab Bag of Interesting Stuff. Higher Order types. Type constructors are higher order since they take types as input and return types as output. Some type constructors (and also some class definitions) are even higher order, since they take type constructors as arguments.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Grab Bag of Interesting Stuff' - sacha-rich


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

Higher order types
Higher Order types

  • Type constructors are higher order since they take types as input and return types as output.

  • Some type constructors (and also some class definitions) are even higher order, since they take type constructors as arguments.

  • Haskell’s Kind system

    • A Kind is haskell’s way of “typing” types

    • Ordinary types have kind *

      • Int :: *

      • [ String ] :: *

    • Type constructors have kind * -> *

      • Tree :: * -> *

      • [] :: * -> *

      • (,) :: * -> * -> *


The functor class
The Functor Class

class Functor f where

fmap :: (a -> b) -> (f a -> f b)

  • Note how the class Functorrequires a type constructor of kind * -> *as an argument.

  • The method fmap abstracts the operation of applying a function on every parametric Argument.

a

a a

Type T a =

x

x x

(f x)

(f x) (f x)

fmap f


Notes
Notes

  • Special syntax for built in type constructors

    (->) :: * -> * -> *

    [] :: * -> *

    (,) :: * -> * -> *

    (,,) :: * -> * -> * -> *

  • Most class definitions have some implicit laws that all instances should obey. The laws for Functor are:

    fmap id = id

    fmap (f . g) = fmap f . fmap g


Instances of class functor
Instances of class functor

data Tree a = Leaf a

| Branch (Tree a) (Tree a)

instance Functor Tree where

fmap f (Leaf x) = Leaf (f x)

fmap f (Branch x y) =

Branch (fmap f x) (fmap f y)

instance Functor ((,) c) where

fmap f (x,y) = (x, f y)


More instances
More Instances

instance Functor [] where

fmap f [] = []

fmap f (x:xs) = f x : fmap f xs

instance Functor Maybe where

fmap f Nothing = Nothing

fmap f (Just x) = Just (f x)


Other uses of higher order t c s
Other uses of Higher order T.C.’s

data Tree t a = Tip a

| Node (t (Tree t a))

t1 = Node [Tip 3, Tip 0]

Main> :t t1

t1 :: Tree [] Int

data Bin x = Two x x

t2 = Node (Two(Tip 5) (Tip 21))

Main> :t t2

t2 :: Tree Bin Int


What is the kind of tree
What is the kind of Tree?

  • Tree is a binary type constructor

    • It’s kind will be something like: ? -> ? -> *

  • The first argument to Tree is itself a type constructor, the second is just an ordinary type.

    • Tree :: (* -> *)-> * -> *


Functor instances of tree
Functor instances of Tree

instance Functor (Tree2 Bin) where

fmap f (Tip x) = Tip(f x)

fmap f (Node (Two x y)) =

Node (Two (fmap f x) (fmap f y))

instance Functor (Tree2 []) where

fmap f (Tip x) = Tip(f x)

fmap f (Node xs) = Node (map (fmap f) xs)


Can we do better
Can we do better

instance Functor t => Functor (Tree2 t) where

fmap f (Tip x) = Tip(f x)

fmap f (Node xs) = Node (fmap (fmap f) xs)


The monad class
The Monad Class

Note m is a

type constructor

class Monad m where

(>>=) :: m a -> (a -> m b) -> m b

(>>) :: m a -> m b -> m b

return :: a -> m a

fail :: String -> m a

p >> q = p >>= \ _ -> q

fail s = error s


Generic monad functions
Generic Monad functions

sequence :: Monad m => [m a] -> m [a]

sequence = foldrmcons (return [])

where mcons p q = do x <- p

xs <- q

return (x:xs)

sequence_ :: Monad m => [m a] -> m ()

sequence_ = foldr (>>) (return ())

mapM :: Monad m => (a -> m b) -> [a] -> m [b]

mapM f as = sequence (map f as)

mapM_ :: Monad m => (a -> m b) -> [a] -> m ()

mapM_ f as = sequence_ (map f as)

(=<<) :: Monad m => (a -> m b) -> m a -> m b

f =<< x = x >>= f


Files and handles
Files and Handles

  • The functions:

    import System.IO

    writeFile:: FilePath -> String -> IO ()

    appendFile :: FilePath -> String -> IO ()

    are used to read and write to files, but they incur quite a bit of overhead if they are used many times in a row. Instead we wish to open a file once, then make many actions on the file before we close it for a final time.

    openFile :: FilePath -> IOMode -> IO Handle

    hClose :: Handle -> IO ()

    data IOMode = ReadMode | WriteMode | AppendMode

    deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)


File modes
File Modes

  • A file mode tells how an open file will be used. Different modes support different operations.

  • When in WriteMode

    hPutChar :: Handle -> Char -> IO ()

    hPutStr :: Handle -> String -> IO ()

    hPutStrLn :: Handle -> String -> IO ()

    hPrint :: Show a => Handle -> a -> IO ()

  • When in ReadMode

    hGetChar :: Handle -> IO Char

    hGetLine :: Handle -> IO String


Standard channels and errors
Standard Channels and Errors

  • Predefined standard Channels

    stdin, stdout, stderr :: Handle

  • Error Handling while doing IO

    isEOFError :: IOError -> Bool

    -- Test if the EOF error

    ioError :: IOError -> IO a

    -- Raise an IOError

    catch :: IO a -> (IOError -> IO a) -> IO a

    -- Handle an Error

  • Other IO types of errors and their predicates.

    isAlreadyExistsError, isDoesNotExistError, 

    isAlreadyInUseError, isFullError, 

    isEOFError, isIllegalOperation,

    isPermissionError, isUserError, 


Ioerror
IOError

  • IOError is an abstract datatype

    • NOT and algebraic datatype, defined with data like [ ] orTree

  • Thus it does not admit pattern matching.

  • Hence the use of all the IOError recognizing predicates.

    • isAlreadyExistsError, isDoesNotExistError, 

    • isAlreadyInUseError, isFullError, 

    • isEOFError, isIllegalOperation,

    • isPermissionError, isUserError

  • This was a concious decision, made to allow easy extension of the kinds of IOErrors, as the system grew.


Handling io errors
Handling IO Errors

  • Any action of type IO a may potentially cause an IO Error.

  • The function

    catch ::IO a -> (IOError -> IO a) -> IO a

    can be used to gracefully handle such an error by providing a “fix”

    getChar' :: IO Char

    getChar' = catch getChar

    (\ e -> return '\n')

    getChar2 :: IO Char

    getChar2 = catch getChar

    (\ e -> if isEOFError e

    then return '\n'

    else ioError e) –- pass non EOF errors on


An example
An Example

getLine' :: IO String

getLine' = catch getLine''

(\ e -> return

("Error: " ++ show e))

where getLine'' =

do { c <- getChar2

; if c == '\n'

then return ""

else do { l <- getLine'

; return (c:l)

}

}


Catching errors when opening files
Catching errors when opening files

getAndOpenFile :: String -> IOMode -> IO Handle

getAndOpenFile prompt mode =

do { putStr prompt

; name <- getLine

; catch (openFile name mode)

(\e -> do { putStrLn

("Cannot open: "++name)

; print e

; getAndOpenFile prompt mode

})

}


Copying files
Copying Files

main =

do { fromHandle <- getAndOpenFile

"Copy from: " ReadMode

; toHandle <- getAndOpenFile

"Copy to: " WriteMode

; contents <- hGetContentsfromHandle

; hPutStrtoHandle contents

; hClosefromHandle

; hClosetoHandle

; putStr "Done\n"

}


ad