Se utdraget ur "AGentle Introduktion.." Appendix (bihang) till Hutton.

Relevanta dokument
Föreläsning 3 i Programmeringsparadigm

Föreläsning 7 i programmeringsparadigm. Ytterligare Högre ordningens funktioner: filter, foldr foldl. Hutton 7.2, 7.3 och 7.4.

Haskell forts. 5DV085 - Programspråk. Jan Erik Moström, Department of Computing Science, Umeå University - jem@cs.umu.se

Nada, KTH Tentamensdag maj -24 Tentamen i Funktionell Programmering Skrivtid 5 h

Föreläsning 4 (och 5?) i programmeringsparadigm.

Del : Funktionell programmering. I alla deluppgifterna, använd Haskell och skriv typen för de identifierare du definierar.

Introduktion till programmering. Standardfunktioner. Vad används datorer till? Standardfunktioner. Föreläsning 2. Prelude. $ ghci...

Funktionell programmering DD1361

Tentamensdag 2002-aug-20 Tentamen i Funktionell Programmering Skrivtid 5 h

I kapitel 15 gör Hudak för reaktiva animeringar detsamma som han i kapitel 13 gör för animeringar. Resultatet är en module Fal.

Introduktion till Haskell

Föreläsning 5 i programmeringsparadigm. Tips kring programmering i Haskell och kring labbarna.

DD1361 Programmeringsparadigm. Carina Edlund

Men först: Några funktioner ur preluden. Introduktion till programmering. Uppgiften. Variationer av uppgiften. Föreläsning 4

Nada Tentamensdag 2004 okt 18 Tentamen Programmeringsparadigm Skrivtid 5 h

Enjoy Vattenfallsmodellen i funktionella språk

Föreläsning 5 i programmeringsparadigm.

Föreläsning 4 i programmeringsparadigm.

Kap9. Operatorn.. Hudak 9.4 sid 11. Fermats förmodan, eller Fermats stora sats säger att. xm + ym == zm har heltalslösningar om och endast om m == 2.

Kungliga Tekniska Högskolan Ämneskod 2D1370 Tentamensdag 2001-maj-31 Tentamen i Funktionell Programmering Skrivtid 4 h

Enjoy Vattenfallsmodellen i funktionella språk

Föreläsning 4 (och 5?) i programmeringsparadigm.

Föreläsning 8. Hudak kapitel 13. 2D1370 Funktionell programmering v15 torsdag

Föreläsning 6 i programmeringsparadigm. Tips kring programmering i Haskell och kring labbarna.

Välkomna till DIT012 IPGO. Tyvärr en bug i Google Docs: Sidnummer stämmer inte alltid. Alla anteckningar börjar på sidan 1.

Senast. Idag. Icke-strikt evaluering. Strikt evaluering. Testa latheten! Lat evaluering. Plus och minus med lat evaluering. Testa latheten!

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Tecken & Strängar. Kapitel 7

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion

Repetition av OOP- och Javabegrepp

Obligatorisk uppgift 5

Repetition av OOP- och Javabegrepp

Programkonstruktion och datastrukturer. Moment 9 Om högre ordningens funktioner. PKD 2010/11 moment 9 Sida 1 Uppdaterad

Pascal... Pascal. Pascal... Pascal...

Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E. Föreläsning 4: Villkor och rekursion. Modulus-operatorn.

Pascal. reserverade ord fördefinierade funktioner och procedurer egendefinierade funktioner, procedurer och objekt

Intro. Vad är en monad?

Föreläsning 10 Datalogi 1 DA2001. Utskrift på skärmen. Syntax. print( Hej ) Hur är det? Hej. print( Hej,end= ) print( Hur är det? ) HejHur är det?

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson 2

Dagens föreläsning Programmering i Lisp Fö 5

Föreläsning 8. Paradigmöversikt, paradigmhistoria, paradigmgeografi. Se även föreläsning 1.

Sista delen av kursen

Programspråkslingvistik. Sista delen av kursen. Ett programspråk

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Del : Paradigmer allmänt.

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Sista delen av kursen

Föreläsning 2 Programmeringsteknik DD1310. Programmering. Programspråk

Föreläsning 2 Programmeringsteknik och C DD1316. Programmering. Programspråk

F6: Högre ordningens funktioner. Mönster för rekursion (1) Mönster för rekursion (1b) Mönster för rekursion (2) Högre Ordningens Funktioner

Del : Paradigmer allmänt.

Dagens föreläsning. Diverse Common Lisp. Konstanter, parametrar, globala variabler

Föreläsning Datastrukturer (DAT036)

Språket Python - Del 1 Grundkurs i programmering med Python

Föreläsning Datastrukturer (DAT036)

Sekvensdatatyper, ASCII och chiffer. Linda Mannila

Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)

Föreläsning 2 Datastrukturer (DAT037)

E02 "The Review" Föreläsning 2, HT2013 Grunderna, repetition. Johan Leitet. Kurs: 1dv403 Webbteknik I

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

Grundläggande datalogi - Övning 1

Introduktion till programmering SMD180. Föreläsning 2: Variabler, uttryck och satser

Objektorienterad programmering D2

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 9 Om högre ordningens funktioner. PK1&PM1 HT-06 moment 9 Sida 1 Uppdaterad

Programmeringsteknik med C och Matlab

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Idag: Par och listor. Symboler. Symboler används för att uttrycka icke-numeriska data såsom namn, adress, bilregisternummer, boktitel, osv.

Lite skoj - typ. 5DV085 - Programspråk. Jan Erik Moström, Department of Computing Science, Umeå University - jem@cs.umu.se

Klassdeklaration. Metoddeklaration. Parameteröverföring

Konvertering från sträng. Winstrand Development

Föreläsning 2 sept 05 (Onsdag v 36). DD Chapter 2.

Idag: Par och listor. Scheme. DA2001 (Föreläsning 6) Datalogi 1 Hösten / 29

TDDC74 Lab 02 Listor, sammansatta strukturer

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

MATLAB. Python. Det finns flera andra program som liknar MATLAB. Sage, Octave, Maple och...

Programkonstruktion. Tentamen,

Inledande programmering med C# (1DV402) 27+15=42 1 (22)

Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad

Grundläggande Datalogi

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

Del : Funktionell programmering. I alla deluppgifterna, använd Haskell och skriv typen för de identifierare du definierar.

TDIU01 - Programmering i C++, grundkurs

Programkonstruktion och datastrukturer. Moment 9 Om högre ordningens funktioner. PKD 2011/12 moment 9 Sida 1 Uppdaterad

I Skapa Hej.java och skriv programmet. I Kompilera med javac Hej.java. I Rätta fel och repetera tills du lyckas kompilera ditt program

Objektorienterad Programmering (TDDC77)

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Föreläsning 6: Introduktion av listor

Föreläsning 2 Programmeringsteknik och C DD1316

Att skriva till och läsa från terminalfönstret

Föreläsning 8. newtype Chess = Chess [(Square, Chessman)] -- data ist f newtype OK -- data istället för newtype krävs om >1 konstruerare.

Exempelsamling Assemblerprogrammering

Allmänt om Mathematica

IEC Delstandard av IEC 61131, vilken totalt består av

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Python. Datatyper. Mer om datatyper. Heltal - 3 Flyttal - 2,456 Listor - [1,2,3,4] Strängar - spam!

Tentamen i Grundläggande Programvaruutveckling, TDA548

n Detta för att kunna koncentrera oss på n Tal: number? n Symboler: symbol? n Strängar: string? n Tecken: char? n Boolskt: boolean?

Sätt att skriva ut binärträd

Transkript:

Föreläsning 3 i Programmeringsparadigm Repetition : Att definiera en funktion i Haskell. Labhäftet p 11. Layoutregler Hutton 2.4.3 p 26. Skåpregler för where and let. Vad vi hitills behanlat i Hutton, se slutet på föreläsningshäfte 2. Att gör egna datatyper. Se utdraget ur "AGentle Introduktion.." Appendix (bihang) till Hutton. Moduler, Abstrakta Data Typer (ADT). Exempel: ADT Complex( annan lösning än nedan) och ADT Date finns på /info/progp02/haskelllectures/f3. Där finns även en del andra program. Signaturbild och moduler för ADT Complex Float imagpart phase realpart mkcart magnitude mkpolar add sub mul Bool == /= neg Complex show String Pil Fet stil Cirkel funktion exporteras symboliserar alla värden i en datatyp

module Complex ( -- 4 a - Complex, mkcart, -- :: Float -> Float -> Complex ex (mkcomplex 1.0 1.0) är 1+i mkpolar, -- :: Float -> Float -> Complex ex (mkpolar 1.0 0.0) är 1+0i realpart, -- :: Complex -> Float ex realpar(mkcomplex 1.0 2.0) är 1.0 imagpart, -- :: Complex -> Float ex imagpart(mkcomplex 1.0 2.0) är 2.0 magnitude, -- :: Complex -> Float ex magnitud(mkcomplex 1.0 1.0) är 1.41... phase, -- :: Complex -> Float ex phase(mkcomplex 1.0 1.0) är 3.14../4.0 conjugate -- :: Complex -> Complex ex conjugate(mkcomplex 1.0 1.0) är 1-i add, -- Complex -> Complex -> Complex additon sub, -- Complex -> Complex -> Complex subtraktion mul, -- Complex -> Complex -> Complex multiplikatuontraktion neg, -- Complex -> Complex negering absval -- Complex -> Double absolutbelopp ) where -- funktionernas typer som ovan data Complex = C Float Float deriving (Eq,Show, Read) mkcart = C mkpolar m p = C ( m* cos p) (m * sin p) realpart (C x _) = x imagpart (C _ y) = y magnitude (C x y) = sqrt(x*x + y*y) phase (C 0 0) = 0 phase (C x y) = atan2 y x conjugate (C x y) = C x (-y) add (C a1 b1) (C a2 b2) = C (a1 + a2) (b1 + b2) sub (C a1 b1) (C a2 b2) = C (a1 - a2) (b1 - b2) mul (C a1 b1) (C a2 b2) = C (a1*a2- b1*b2) (a1*b2 +b1* a2) absval z = mkcart (magnitude z) 0.0 instance Num Complex where -- kan vi inte än (+) = add (-) = sub (*) = mul negate = neg abs = absval frominteger i = error "frominteger" signum z = error "signum in Complex" frominteger n = error " frominteger in Complex" På /info/progp02/haskelllectures/f3/complex.hs finns en annan lösning. Något om typklasser och "overloading" (Hutton 3.9, Fokker p 17, C&K p 5, 76). Något om ADT och moduler (C&K p 11, Chapter 10, "A Gentle Introduction i Labhäftet p 17.)

Listprogrammering i funktionella språk. Polymorfism. Tupler. Listor: Om vi gjorde det själva: Inbyggt i Preluden. OBS Speciell syntax! data List a = Nil data [a ] = [] Cons a (List a) a : [a] Listor har alltså konstruerararna [] :. Konstruerarna kan används i mönster. Speciella syntax för bekvämlighets skull:[1,2] == 1:2:[] Vad utmärker rekursiva datatyper? Del av värden i typen av samma typ. Kan vara "godtyckligt stora". Godtyckigt många element, alla av samma typ. Men allt tillåtet, t ex lisor med listor med... Strängar : Listor med Characters dvs i Preluden String = [Char]. Speciella syntax för bekvämlighets skull: "hej" == [ h, e, j ] == h : ( e :( j :[]])) :: [Char] Allt man kan göra, alla funktioner för listor användbara för strängar. Tupler: Inbyggt i Preluden. OBS Speciell syntax! Tupler, t ex par : data (a, b) = (a,b). Konstruerare (, ). Konstruerarna kan används i mönster. Fixt antal komponenter, som kan vara av olika typ. T ex ([[Char]], Int, ( [(Int,Bool)],String) Exempel: sum (Hutton 1.5 p 17Fokker p 13), prod (hutton 6.2 p 67C&K p 26 ), length (Hutton 6.2 p67, Fokker p 13, C&K p 74 ), När man skriver typer i typuttryck används stor initialbokstav för typer. Namn med små bokstäver i typuttryck betyder "vilken typ som helst". T ex length:: [a] -> Int.Detta kallas i Haskell polymorfism (Hutton 3.7, Fokker p 16, C&Kp 28 p 74). Dock : Om man till exempel skriver Num a => [a] -> a betyder a alla typer som är medlemmar i Num-gruppen, eller med Haskellterminologi : alla typer som är instanser i typklassen Num. Vi har inte sagt så mycket om typklasser än, hur de definieras och används kommer senare. Typklasser möjliggör overloading, som nämts tidigare. (++) (Hutton 6.2 p68, Fokker p 39, C&K p 28 ), zip (hutton 6.3 p 69.Fokker p 56 ) I Hutton har vi nu gjort det mesta överhoppade i kap 3 och 4, dock ek 4.5 och 4.6. Dessutom i Hutton har vi behandlat kapitele 6 utom lite svårare rekursion i 6.4 och 6.5. I Fokker bör nu de mesta i kapitel 1 kunna läsas och förstås, märk dock att en del praktiska saker gäller Gopher och inte Hugs som vi använder. Det vi inte behandlat än är 1.3.6 Functions on functions. C&K bör nu de mesta i kapitel 1, 3, 4, 8 kunna läsas och förstås

Ett exempel : "Korrekta" (Gratis blinummer, numera kan man mot betalning ha andra skyltar) bilnummer. Programmet, som visar att man ibland använder smarta mönster för att skriva eleganta program, finns på /info/progp02/haskelllectures/f4. module Bilnummer where ischarinrange :: Char -> (Char, Char) -> Bool ischarinrange c (cfrom, cto) = cfrom <= c && c <= cto {- eller? ischarinrange :: Char -> Char - > Char -> Bool ischarinrange c cfrom cto = cfrom <= c && c <= ct -- anropas som ischarinrange c A Z -} isuppercase :: Char -> Bool isuppercase c = ischarinrange c ( A, Z ) notusedletters :: String -- det samma som [Char] notusedletters = "IQV" -- == [ I, Q, U ] == I :( Q :( U : [] )) islegalletter :: Char -> Bool islegalletter c = isuppercase c && (not (elem c notusedletters)) -- Snyggare? c elem notusedletters islegal :: String -> Bool islegal (b1:b2:b3: :s1:s2:s3:[]) --"avancerat mönster " = ischarinrange b1 ( A, T ) && isdigit s2 && isdigit s1 && isdigit s3 && islegalletter b1 && islegalletter b2 && islegalletter b3 islegal _ = False -- isdigit :: Char -> Bool i Prelude -- elem :: Eq a => a -> [a] -> Bool i Prelude {- En tänkbar definition av elem är elemlk :: Eq a => a -> [a] -> Bool elemlk x (y:ys) = (x == y) (x elemlk ys) elemlk x [] = False -}

Hur hittar man "fördefinierade namn (funktioner)"? ( dvs exporterade namn från Prelude) Det är förstås jobbigt att komma ihåg alla fuktioner som finns i Prelude, det kan var lika bekvämt att skriva dem själv (oftast en, två eller tre rader). I slutet på Hutton finns en lista över några funktioner. Man kan titta på och söka med Search i preluden ( skriven i Haskell till största delen) med emacs, filnamn kopieras lämpligen, finns i ingressen när du startar hugs.)..> emacs /pkg/hugs98/dec01/os/share/hugs/lib/prelude.hs & Nedan finns är början på filen Prelude.hs. De vikigaste namnen i mitt tycke har jag skrivit med fet stil. De flesta av dessa kommer att introduceras under kursens gång. Längre ned i filen finns namnens definitionerna, i regel i Haskell, som man ofta kan förstå om man inte direkt av namnet (och typen, gör :i <namnet> i hugs ) förstår vad namnet står för. module Prelude ( -- module PreludeList, -- Listfunktioner map, (++), concat, filter, head, last, tail, init, null, length, (!!), foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1, iterate, repeat, replicate, cycle, take, drop, splitat, takewhile, dropwhile, span, break, lines, words, unlines, unwords, reverse, and, or, any, all, elem, notelem, lookup, sum, product, maximum, minimum, concatmap, zip, zip3, zipwith, zipwith3, unzip, unzip3, ReadS, ShowS, Read(readsPrec, readlist), Show(show, showsprec, showlist), reads, shows, read, lex, showchar, showstring, readparen, showparen, -- module PreludeIO, -- IO MM FilePath, IOError, ioerror, usererror, catch, putchar, putstr, putstrln, print, getchar, getline, getcontents, interact, readfile, writefile, appendfile, readio, readln, -- module Ix, Ix(range, index, inrange, rangesize), -- module Char, isascii, iscontrol, isprint, isspace, isupper, islower, isalpha, isdigit, isoctdigit, ishexdigit, isalphanum, digittoint, inttodigit, toupper, tolower,ord, chr, readlitchar, showlitchar, lexlitchar, -- module Numeric showsigned, showint, readsigned, readint, readdec, readoct, readhex, readsigned, readfloat, lexdigits, -- module Ratio, Ratio, Rational, (%), numerator, denominator, approxrational, -- Non-standard exports IO(..), IOResult(..), primexitwith, Addr, Word, StablePtr, ForeignObj,basicIORun, blockio, IOFinished(..), threadtoioresult, HugsException, catchhugsexception, primthrowexception, Bool(False, True), Maybe(Nothing, Just), -- Standardtyper Either(Left, Right), Ordering(LT, EQ, GT),

Char, String, Int, Integer, Float, Double, IO, -- List type: []((:), []) -- Tuple types: (,), (,,), etc. -- Trivial type: () -- Functions: (->) Rec, EmptyRec, EmptyRow, -- non-standard, should only be exported if TREX Eq((==), (/=)), -- Relationsoperatorer Ord(compare, (<), (<=), (>=), (>), max, min), Enum(succ, pred, toenum, fromenum, enumfrom, enumfromthen, enumfromto, enumfromthento), Bounded(minBound, maxbound), -- Numeriska operatorer -- Num((+), (-), (*), negate, abs, signum, frominteger), Num((+), (-), (*), negate, abs, signum, frominteger, fromint), Real(toRational), -- Integral(quot, rem, div, mod, quotrem, divmod, tointeger), Integral(quot, rem, div, mod, quotrem, divmod, even, odd, tointeger, toint), -- Fractional((/), recip, fromrational), -- Flyttal, matte funk. Fractional((/), recip, fromrational, fromdouble), Floating(pi, exp, log, sqrt, (**), logbase, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh), RealFrac(properFraction, truncate, round, ceiling, floor), RealFloat(floatRadix, floatdigits, floatrange, decodefloat, encodefloat, exponent, significand, scalefloat, isnan, isinfinite, isdenormalized, isieee, isnegativezero, atan2), Monad((>>=), (>>), return, fail), Functor(fmap), mapm, mapm_, sequence, sequence_, (=<<), maybe, either, (&&), ( ), not, otherwise, -- Boolska operatorer subtract, even, odd, gcd, lcm, (^), (^^), fromintegral, realtofrac, -- Diverse fst, snd, curry, uncurry, id, const, (.), flip, ($), until, astypeof, error, undefined, seq, ($!) ) where -- Standard value bindings {Prelude} --------------------------------- infixr 9. infixl 9!! infixr 8 ^, ^^, ** infixl 7 *, /, quot, rem, div, mod, :%, % infixl 6 +, - --infixr 5 : -- this fixity declaration is hard-wired into Hugs infixr 5 ++ infix 4 ==, /=, <, <=, >=, >, elem, notelem infixr 3 && infixr 2 infixl 1 >>, >>= infixr 1 =<< infixr 0 $, $!, seq

Ett Exempel till :Signaturbild och moduler ADT Date Bool yearjan0tojulian leapyear Int Julian Year DayOfMonth January Febrary March April Month Dat date juliantodate datetojulian daynumberthisyear (-#) (+#) (-##) (+##) show date1 Date May June July August September October November December String show next dayofweek Monday Thuesday Wedensday show Day Thursday Friday Saturday Sunday

----------------------------------------------------------------------------------------------------------------------------- module Date where -- på /info/progp02/haskelllectures/f3/date.hs data Date = Dat Int Month Int deriving ( Show, Eq, Ord) data Month = January February March April May June July August September October November December deriving ( Show, Eq, Ord, Enum) data Day = Monday Thuesday Wedensday Thursday Friday Saturday Sunday deriving ( Show, Eq, Ord, Enum) type Julian = Int type Year = Int type DayOfMonth = Int date :: Year {- Int -} -> Month -> DayOfMonth -> Date date = Dat date1 :: Year -> Int -> DayOfMonth -> Date date1 y mi d = Dat y (toenum (mi - 1)) d leapyear :: Year -> Bool leapyear y = (y mod 4 == 0) && (not(y mod 100 == 0 )) (y mod 400 == 0) daynumberthisyear:: Date -> Int daynumberthisyear (Dat y m d) = daynumberthisyearx (Dat y m d) (Dat y January 1) 1 where daynumberthisyearx:: Date -> Date -> Int -> Int daynumberthisyearx d1 d2 i d1 == d2 = i otherwise = daynumberthisyearx d1 (next d2) (i+1) yearjan0tojulian:: Year -> Julian yearjan0tojulian y = -320 + (y-1858)*365 + (y-1857) div 4 - (y-1801) div 100 + (y-1601) div 400 datetojulian :: Date -> Julian datetojulian (Dat y m d) = yearjan0tojulian y + daynumberthisyear (Dat y m d) juliantodate :: Julian -> Date juliantodate i = juliantodatex i (Dat 1858 November 17) where juliantodatex:: Julian -> Date ->Date juliantodatex i (Dat y m d) datetojulian (Dat y m d) == i = Dat y m d datetojulian (Dat (y+1) January 1)<i = juliantodatex i (Dat (y+1) January 1) otherwise = juliantodatex i (next (Dat y m d)) next :: Date -> Date next (Dat y January 31) = Dat y February 1 next (Dat y February 28) leapyear y = Dat y February 29 otherwise = Dat y March 1 next (Dat y February 29) = Dat y March 1 next (Dat y March 31) = Dat y April 1 next (Dat y April 30) = Dat y May 1 next (Dat y May 31) = Dat y June 1 next (Dat y June 30) = Dat y July 1 next (Dat y July 31) = Dat y August 1 next (Dat y August 31) = Dat y September 1 next (Dat y September 30)= Dat y October 1 next (Dat y October 31) = Dat y November 1 next (Dat y November 30) = Dat y December 1 next (Dat y December 31) = Dat (y+1) January 1

next (Dat y m d ) = Dat y m (d+1) dayofweek :: Date -> Day dayofweek d = dayofweeki (datetojulian d mod 7 ) {- where dayofweeki :: Int -> Day dayofweeki 1 = Wedensday dayofweeki 2 = Thursday dayofweeki 3 = Friday dayofweeki 4 = Saturday dayofweeki 5 = Sunday dayofweeki 6 = Monday dayofweeki 0 = Thuesday -} where dayofweeki :: Int -> Day dayofweeki j = toenum ((j+1) mod 7) (-#) :: Date -> Date -> Int (-#) d1 d2 = datetojulian d1 - datetojulian d2 (+#) :: Date -> Date -> Int (+#) d1 d2 = datetojulian d1 + datetojulian d2 (+##) :: Date -> Int -> Date (+##) d1 i = juliantodate (datetojulian d1 + i) (-##) ::Date -> Int -> Date (-##) d1 i = juliantodate (datetojulian d1 - i)