On Github chritchens / haskell-talk
a strongly typed functional programming language
with polimorphic types
based on the simply typed lambda calculus
with automatic type inference and checking
and no side effects
If it compiles it just works
No side effects means safety
Functional programming allows you to stay high level
enhancing good design patterns by default
and make easy hard things (e.g. Quickcheck, Pandoc, xmonad)
Embedded languages as Ivory and programmin languages as Idris
Embedded systems as UAVs software
Compilers
Type-safe Web Frameworks as Yesod
Type-safe database management as in Persistent
You define functions like this:
{-| foo is a function without type signature x and y are its variables the compiler will rise an exception when the function will be invoked with uncomparable variables -} foo x y = if x > y then x else y -- bar is a function with type signature -- and a safe interface to foo bar :: Int -> Int -> Bool bar x y = foo x y
You bind local variables with `let... in`
foobar :: Float -> Float -> Float foobar x y = let z = cos x in z*x*y
or where
foobar :: Double -> Double -> Double foobar x y = z*x*y where z = cos x
recursive functions with pattern matching
fact n = | n == 0 = 0 | otherwise = n * (fact n - 1)
Overloaded functions
map f [] = [] map f x:xs = f x : map f xs
Pattern matching with case
map f l = case l of ([]) -> [] (x:xs) -> f x : map xs
or with guards
filter p [] = [] filter p (x:xs) = | p y = y : filter p ys | otherwise = filter p ys
Lambda expressions
-- takes a variable a and return -- the application of f on a fun f = \a -> f a
You can define different kind of types:
product types are n-uples
data Phone = Phone Vendor OS
sum types are enumerations
data OS = Android | IOs
datatypes are aliased types
datatype Vendor = String
Polymorphic types
data Maybe a = Just a | Nothing data Either a b = Left a | Right b
Pattern matching types
maybeDouble :: (a :: Maybe Numeric) => a -> a maybeDouble x = | Just k -> Just (k*2) | otherwise -> Nothing
class Monoid a where -- the identity element mempty :: a -- the associative operation (+, *, etc) mappend :: a -> a -> a -- reduce the list of elements of type a -- using mappend as operation mconcat :: [a] -> a -- mconcat = foldl mempty mappend mconcat = foldr mappend mempty
Any instance of Monoid have to satisfy these rules:
-- mempty is the identity element w.r.t mappend mempty `mappend` x = x x `mappend` mempty = x -- mappend is associative (x `mappend` y) `mappend` z = x `mappend` (y `mappend` z)
-- lists are monoids instance Monoid [a] where mempty = [] mappend = (++) mconcat = foldr mappend mempty
class Functor f where fmap :: (a -> b) -> f a -> f b
fmap id = id -- '.' is function composition and it -- works as in mathematics fmap (g . h) = (fmap g) . (fmap h)
instance Functor [] where fmap _ [] = [] -- ':' is the operator for list -- concatenation fmap g (x:xs) = g x : fmap g xs
class Foldable t where fold :: Monoid m => t m -> m foldMap :: Monoid m => (a -> m) -> t a -> m foldr :: (a -> b -> b) -> b -> t a -> b foldl :: (a -> b -> a) -> a -> t b -> a foldr1 :: (a -> a -> a) -> t a -> a foldl1 :: (a -> a -> a) -> t a -> a
instance Foldable [] where foldMap g = mconcat . map g data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) instance Foldable Tree where foldMap f Empty = mempty foldMap f (Leaf x) = f x foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r
class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b
-- identity law pure id <*> v = v -- homomorphism pure f <*> pure x = pure (f x) -- interchange u <*> pure y = pure ($ y) <*> u
instance Applicative [] where pure x = [x] -- array comprehension gs <*> xs = [ g x | g <- gs, x <- xs ]
class Monad m where return :: a -> ma (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b m >> n = m >>= \_ -> n fail :: String -> m a
return a >>= k = k a m >>= return = m m >>= (\x -> k x >>= h) = (m >>= k) >>= h fmap f xs = xs >>= return . f
The "do { x <- foo; bar x }" is syntactic sugar for "foo >>= \x -> bar"
f :: (Monad m) => m b f = do -- x :: b -- foo :: m a -> m b x <- foo -- bar :: b -> m c bar x
instance Monad Maybe where -- return :: a -> Maybe a return = Just -- (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b (Just x) >== g = g x Nothing >>= _ = Nothing -- m >> n = m >>= \_ -> n instance Monad IO where -- return :: a -> IO a return = IO -- (>>=) :: IO a -> (a -> IO b) -> IO b (IO x) >>== g = g x main :: IO () -- putStr :: String -> IO () main = do putStr "What is your name?" -- readLn :: Read a => IO a -- a is an instance of Read -- so it has a method read -- to convert it from String a <- readLn putStr "How old are you?" b <- readLn -- print :: Show a => a -> IO () -- a is an instance of Show, so -- it has a method show to convert -- it to String print (a, b) main2 = putStr "What is your name?" >> readLn >>= \a -> putStr "How old are you?" >> readLn >>= \b -> print (a, b)
You can *hask* me anything about Haskell from 25pm to 26pm.