1 / 27

Introduction to Haskell and ForSyDe

Introduction to Haskell and ForSyDe. Axel Jantsch March 2001. The Origin of Functional Languages. Alonzo Church, The Calculi of Lambda Conversion , 1941. (1932-33) Church-Rosser theorem, 1936. Unique normal form for l expressions (“value” of an expression);

Download Presentation

Introduction to Haskell and ForSyDe

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to Haskell and ForSyDe Axel JantschMarch 2001

  2. The Origin of Functional Languages • Alonzo Church, The Calculi of Lambda Conversion, 1941. (1932-33) • Church-Rosser theorem, 1936. • Unique normal form for l expressions (“value” of an expression); • Normal-order reduction yields normal form; • Fixed-point theorem: Every l expression e has a fixed-point e’ such that e e’ = e’. • Every recursive function can be written non-recursively. • Church’s thesis: “Effectively computable functions from positive integers to positive integers are just those definable in the l calculus.” • Turing 1937: “Turing-computability is equivalent to l-definability.” Axel Jantsch, ESDlab, KTH

  3. Influential Functional Languages • McCarthy 1960: LISP: • Applicative-order reduction with conditionals; • Lists and higher-order operations on lists; • Garbage collection; • Use of S-expressions (abstract syntax) to represent both data and program; • Landin 1964-1966: Iswim • Backus 1978: FP • Gordon et al. 1978: ML; Milner 1984: SML: • I/O facility with side effects; • Sophisticated module system; • Exception mechanism; • Innovative typing system (Hindley1969, Milner 1978): • Strongly and statically typed; • Use of inference to determine the type of every expression; • Allows polymorphic functions and data structures; • User defined concrete and abstract types; • Hudak and Wadler 1988: Haskell (after Haskell B. Curry); Axel Jantsch, ESDlab, KTH

  4. Imperative Languages • Turing 1930s: Turing machine; • Fortran 1950s • E.W.Dijkstra, "GOTO statement considered harmful", ACM Comm. vol.11, nr.3, 1968. • Structural programming, Pascal, 1970s • Object Oriented Concepts, 1980s: • Abstract data types • Inheritance • Polymorphic functions Axel Jantsch, ESDlab, KTH

  5. Bibliography • Paul Hudak, "Conception, Evolution, and Application of Functional Programming Languages", ACM Computing Surveys, vol. 21, no. 3, pp. 359-411, September 1989. • The Haskell 98 Report, ed: Simon Peyton Jones, John Hughes, February 1999. • Simon Thompson, Haskell - The Craft of Functional Programming, Addison-Wesley, 2 edition, 1999. • Paul Hudak and Joseph H. Fasel, A Gentle Introduction to Haskell, 1999. • Haskel Home Page: http://haskell.org Axel Jantsch, ESDlab, KTH

  6. Haskell and Skeleton Libraries • Haskell is a general purpose, functional programming language; • Library for perfectly synchronous process networks; • Library for data flow process networks; Axel Jantsch, ESDlab, KTH

  7. Haskell Features - 1 - • Declarative: The program is a list of equations which have to be satisfied; no predefined execution order; • Referential transparancy: y=f(x) • Single assignment: “Variables” are assigned only once; • Higher order functions: Functions are first class citizens and can be used as arguments; • Formal semantics: denotational • Strong type system Axel Jantsch, ESDlab, KTH

  8. Features of Haskell - 2 - • Higher Order Functions map :: (a -> a) -> [a] -> [a] map f [] = [] map f (x:xs)= f x : map f xs mult :: Int -> Int -> Int mult x y = x*y double :: Int -> Int double = mult 2 mapDouble :: [a] -> [a] mapDouble = map double • Lazy Evaluation (non-strict) stupid x y = 2*x stupid 3 (12/3) = 6 stupid 3 (5/0) = 6 -- lazy stupid 3 (5/0) = error -- strict Axel Jantsch, ESDlab, KTH

  9. Features of Haskell - 3 - • Data abstraction module Store (Store, initial, -- Store value, -- Store->Var->Int update --Store->Var->Int->Store ) where • Type system: • strong, static, polymorphic, inference based; • Pattern matching and equations mystery x y | x==0 = y | otherwise = x mystery 0 y = y mystery x y = x Axel Jantsch, ESDlab, KTH

  10. Features of Haskell - 4 - • Polymorphism • Parametric polymorphism map :: (a -> a) -> [a] -> [a] map f [] = [] map f (x:xs)= f x : map f xs • Ad hoc polymorphism (overloading) + :: Int -> Int -> Int + :: Float -> Float -> Float + :: String -> String -> String • Type constraints class Num a where (+) :: a -> a -> a -- read as "a type a belongs to the class -- Num if there is an overloaded -- function + defined on it instance Num Int where x + y = addInt x y addPair :: Num a=> (a,a) -> a addPair (x,y) = x + y Axel Jantsch, ESDlab, KTH

  11. Haskell Example Quicksort in Haskell: qsort :: [Int] -> [Int] qsort [ ] = [ ] qsort (x:xs) = (qsort lt_x) ++ [x] ++ (qsort greq_x) where lt_x = [y | y <- xs, y < x] greq_x = [y | y <- xs, y >= x] Axel Jantsch, ESDlab, KTH

  12. Data and Types Examples: 5 :: Integer 'a' :: Char inc :: Integer -> Integer [1,2,3] :: [Integer] ('b',4) :: (Char,Integer) Build-in types: Int - integer Integer - integer Bool - boolean (True, False) Float - floating point String - string of characters Char - character Axel Jantsch, ESDlab, KTH

  13. Function Types • Many functions are polymorphic, i.e. they operate on different types: length :: [a] -> Integer length [] = 0 length (x:xs) = 1 + length xs head :: [a] -> a head (x:xs) = x tail :: [a] -> [a] tail (x:xs) = xs Axel Jantsch, ESDlab, KTH

  14. Partial Evaluation of Functions mymap = map inc mymap :: [Integer] -> [Integer] mymap [1,2,3] => [2,3,4] monitor :: Show a => String -> a -> a monitorF1 = monitor “file1” add :: Integer -> Integer -> Integer add x y = x+y inc :: Integer -> Integer inc = add 1 map :: (a -> b) -> [a] -> [b] map f [] = [] map f (x:xs) = f x : map f xs Axel Jantsch, ESDlab, KTH

  15. User Defined Types • Type synonyms: type String = [Char] type IntPair = (Int,Int) • Type declarations: data Bool = False | True data Color = Red | Green | Blue deriving (Show,Eq) data Tval a = Abst | Prst a deriving (Eq, Show) data Signal a = NullS | a :- Signal a deriving (Eq, Show) Axel Jantsch, ESDlab, KTH

  16. Lists, Strings, and Tuples l1 = [1,2,3] ++ [4,5,6] => [1,2,3,4,5,6] l2 = 1 : [2,3,4,5,6] => [1,2,3,4,5,6] st1 = [‘a’,’b’,’c’] ++ “efg” => “abcefg” s1 :: Signal Int s1 = signal [1,2,3,4] s2 = s1 +: s1 => 1 :- 2 :- 3 :- 4 :- 1 :- 2 :- 3 :- 4 :- NullS s3 = 0 :- s1 => 0 :- 1 :- 2 :- 3 :- 4 :- NullS s4 :: Signal (Int,Int) s4 = signal [(1,2), (3,4)] => (1,2) :- (3,4) :- NullS type TInt = TVal Int ts1 :: Signal Tint ts1 = signal [Abst, Prst 1, Prst 2] => Abst :- (Prst 1) :- (Prst 2) :- NullS Axel Jantsch, ESDlab, KTH

  17. Infix Operators mapSY :: (a -> b) -> Signal a -> Signal b p1 = mapSY inc s1 = signal [1,2,3] p1 s1 => 2 :- 3 :- 4 :- NullS p2 = mapSY (*2) p2 s1 => 2 :- 4 :- 6 :- NullS p3 = p2 . p1 p3 s1 => 4 :- 6 :- 8 :- NullS • List concatenation: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) • Function composition: (.) :: (b -> c) -> (a -> b) -> (a -> c) (f . g) x = f (g x) Axel Jantsch, ESDlab, KTH

  18. Lazy Evaluation • Only values which are needed are computed. il1 = [1,2..] il2 = [1,3..] take 5 il1 => [1,2,3,4,5] take 3 il2 => [1,3,5] take 5 (drop 5 il1) => [6,7,8,9,10] s1 = signal [1..] takeS 3 s1 => 1 :- 2 :- 3 :- NullS p1 = mapSY inc p2 = mapSY (*2) p3 = p2 . p1 takeS 5 (p3 s1) => 4 :- 6 :- 8 :- 10 :- 12 :- NullS takeS 3 (drop 98 (p3 s1)) => 200 :- 202 :- 204 :- NullS Axel Jantsch, ESDlab, KTH

  19. Pattern Matching • As-patterns f (x:xs) = x : x : xs f s@(x:xs) = x : s • Wild cards: head (x:_) = x tail (_:xs) = xs • Case expressions: take m ys = case (m,ys) of (0,_) -> [] (_,[]) -> [] (n,x:xs) -> x : take (n-1) xs take 0 _ = [] take _ [] = [] take n (x:xs) = x : take (n-1) xs • Guards: sign x | x > 0 = 1 | x== 0 = 0 | x < 0 = -1 sign x | x > 0 = 1 | x== 0 = 0 | otherwise = -1 Axel Jantsch, ESDlab, KTH

  20. Synchronous Library - State-less Skeletons mapSY :: (a -> b) Signal a -> Signal b p1 = mapSY (*2) p1 (1:-2:-3:-NullS) => 2 :- 4 :- 6 :- NullS zipWithSY :: (a -> b -> c) -> Signal a -> Signal b -> Signal c p2 = zipWithSY (*) p2 (1:-2:-3:-NullS) (1:-2:-3:-NullS) => 1 :- 4 :- 9 :- NullS zipWith3SY :: (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d zipWith4SY :: (a -> b -> c -> d -> e) -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e zipSY :: Signal a -> Signal b -> Signal (a,b) zipSY (1:-2:-3:-NullS) (4:-5:-6:-NullS) => (1,4):-(2,5):-(3,6):-NullS) unzipSY :: Signal (a,b) -> (Signal a, Signal b) unzipSY (zipSY (1:-2:-3:-NullS) (4:-5:-6:-NullS)) => ((1:-2:-3:-NullS), (4:-5:-6:-NullS)) Axel Jantsch, ESDlab, KTH

  21. Synchronous Library - State Skeletons scanlSY :: (a -> b -> c) -> a -> Signal b -> Signal a scanlSY f mem NullS = NullS scanlSY f mem (x:-xs) = f mem x :- (scanlSY f newmem xs) where newmem = f mem x scanl2SY :: (a -> b -> c -> d) -> a -> Signal b -> Signal c -> Signal a p1 = scanlSY cntrFn 0 s1 = signal (concat (repeat [True,False])) s2 = p1 s1 takeS 7 s2 => 1 :- 1 :- 2 :- 2 :- 3 :- 3 :- 0 :- NullS cntrFn :: Int -> Bool -> Int cntrFn y x = case (x) of True -> ((y+1) `mod` 4) False -> y Axel Jantsch, ESDlab, KTH

  22. Synchronous Library - State Machines mooreSY :: (a -> b -> c) -> (a -> c) -> a -> Signal b -> Signal a mooreSY nextstate output init = mapSY output . (scanlSY nextstate init) mealySY :: (a -> b -> c) -> (a -> b -> c) -> a -> Signal b -> Signal a mooreSY nextstate output init signal = zipWithSY output (init :- (scanlSY nextstate init signal)) signal p2 = mealySY cntrFn outFn 0 s3 = p2 s1 take 7 s3 => “one” :- “one” :- “two” :- “two” :- “three” :- “three” :- “zero” :- NullS outFn :: Int -> String outFn 0 = “zero” outFn 1 = “one” outFn 2 = “two” outFn 3 = “three” Axel Jantsch, ESDlab, KTH

  23. Synchronous Library - Timed Signals hdTrans :: PacketEv -> PacketEv hdTrans Abs = Abs hdTrans p@((Prst UHd),_) = p hdTrans ((Prst EHd1),b) = ((Prst EHd2),b) hdTrans ((Prst EHd2),b) = ((Prst EHd1),b) p = mapSY hdTrans s1 = (Abst :- (Prst (UHd, [0,1])):-(Prst (EHd1,[])) :- (Prst (EHd2,[]))) p s1 => Abst :- (Prst (UHd, [0,1])):-(Prst (EHd2,[])) :- (Prst (EHd1,[])) type Value = Integer type ValEvent = TVal Value s1 :: Signal ValEvent s1 = signal [Abst, (Prst 1), Abst, (Prst 2)] data Header = UHd | EHd1 | EHd2 type Body = [Int] type Packet = (Header,Body) type PacketEv = TVal Packet Axel Jantsch, ESDlab, KTH

  24. Data Flow Library • Data flow skeletons do not operate on timed signals. • Data flow skeletons allow combinatorial functions which consume several input and output tokens. mapDF :: (a -> b) -> Signal a -> Signal b map12DF :: (a -> (b,b)) -> Signal a -> Signal b map21DF :: ((a,a) -> b) -> Signal a -> Signal b map22DF :: ((a,a) -> (b,b)) -> Signal a -> Signal b mapGen :: Int -> ([a] -> [b]) -> Signal a -> Signal b mapUpDF :: (a -> [b]) -> Signal a -> Signal b mapDownDF :: Int -> ([a] -> b) -> Signal a -> Signal b Axel Jantsch, ESDlab, KTH

  25. Stochastic Processes and Skeletons • sigmaUn generates a signal of uniformly distributed integers within a given range. sigmaUn :: Int -> (Int, Int) -> Signal Int takeS 5 (sigmaUn 3 (0,9)) => 5 :- 5 :- 4 :- 7 :- 3 :- NullS • selMapDF is a stochastic variant of mapDF; it selects one out of two functions to be applied on the input based on a probability distribution. selMapDF :: Int -> (a -> b) -> (a -> b) -> Signal a -> Signal b selScanlDF :: Int -> (a -> b -> a) -> (a -> b -> a) -> a -> Signal b -> Signal a Axel Jantsch, ESDlab, KTH

  26. How to Model with Skeletons ? 1. Draw a process graph. 2. Decide the types of processes: no internal state -> map skeleton internal state same as output -> scanl skeleton output depends only on state -> moore skeleton output depends on input and state -> mealy 3. Define data types of signals and states. 4. Decide on skeleton variants (# inputs, # outputs,…) 5. Design the combinatorial functions Axel Jantsch, ESDlab, KTH

  27. sc sd sa p2 p1 se sb p3 How to Model with Skeletons ? • 6. Compose the processes into a system. p1 :: Signal a -> Signal b -> Signal c p2 :: Signal c -> (Signal d, Signal e) p3 :: Signal e -> Signal b system sa = sd where sd = fst (p2 sc) sc = p1 sa sb sb = p3 se se = snd (p2 sc) Axel Jantsch, ESDlab, KTH

More Related