Home
 

Typen von Funktionen

nextnextupuppreviouspreviouscontentscontents
Next:FunktionsdefinitionenUp:Grundlegende SprachelementePrevious:Typen

Typen von Funktionen

  • higher order functions

    = Funktionen mit Funktionen als Argument und Resultat

    z.B. (numerische) Differentiation:

     diff :: (Float -> Float) -> (Float -> Float)
    
    diff f = g
    where g x = ( f (x + delta) - f x ) / delta
    delta = 0.001

    ( Obacht: Beispiel ist numerisch nicht das Feinste! )

     > diff sin 0
    
    1.0
    > diff cos (pi/2)
    -1.00005
    >diff (diff cos) 0 - 2. Ableitung
    -1.07288

    Beachte Bindekraft und Linksassoziierung von Funktionsanwendung!

     diff sin 0     - ist (diff sin) 0,
    
    - und diff sin :: Float -> Float
    - ( => :type Kommando!)

    Sowas wie

     diff diff cos 0
    

    wird deshalb gegliedert zu

     (diff diff) cos 0
    

    und ergibt Typfehler!

  • Currying

    [Anm.: ( Konzept aus der Mathematischen Logik & Grundlagenforschung; erfunden von Schönfinkel, popularisiert durch Haskell Curry ) ]

    Funktionen mit mehreren Argumenten werden meist aufgefaßt als Funktionen mit Tupel als Argument, z.B.:

    
    
    
    Volumen :: ( R R R ) $\to$ R
    (länge, breite, höhe) $\mapsto$ länge * breite * höhe

    Haskell benutzt andere und äquivalente Auffassung:

     volume :: Float->Float->Float->Float
    
    volume l b h = l*b*h

    deren besonderer Nutzen darin liegt, daß die Argumente sukzessive einzeln kommen können d.h. partielle Funktionsanwendung ist möglich (und ergibt natürlich eine Funktion der restlichen Argumente!):

     > volume 1 1
    
    << Function >>
    > :type volume 1 1
    volume 1 1 :: Float -> Float

    Die durch partielle Anwendung resultierende Funktion läßt sich wie üblich verwenden, z.B.:

     > diff (volume 1 1) 47.11
    
    0.949451

    und zur Bequemlichkeit auch mit einem Namen versehen, z.B.:

     volume_per_unitsquare = volume 1 1
    
    anderes Beispiel:
    Differentiation mit variierbarer Genauigkeit:
     multi_diff :: Float -> (Float -> Float) -> (Float -> Float)
    
    multi_diff d f x = (f (x+d)- f x) / d

    dann kann man definieren:

     coarse_diff = multi_diff 10.0
    
    fine_diff = multi_diff 1.0e-3 - nicht zu klein machen!!

    und rechnen:

     > coarse_diff cos (pi/2)
    
    0.0544021
    > fine_diff cos (pi/2)
    -1.00005

    Damit partielle Anwendung funktioniert, müssen Funktionstypen nach rechts assoziieren:

     volume :: Float -> Float -> Float -> Float
    
    - ist: Float -> (Float -> (Float -> Float))


    multi_diff :: Float -> (Float -> Float) -> (Float -> Float)
    - ist Float -> ((Float -> Float) -> (Float -> Float))

Hier noch mal ausführliche Beispiele:

 ----------------POLYMORPHISM, list-type examples



Prelude> :type []
[] :: [a]
Prelude> :type (:)
(:) :: a -> [a] -> [a]
Prelude> :type 'a':[]
'a' : [] :: [Char]
Prelude> 'a':[]
"a"
Prelude> :type ['a','b','c']:[]
['a','b','c'] : [] :: [[Char]]
Prelude> ['a','b','c']:[]
["abc"]
Prelude> :type ['a','b','c']:['a','b','c']
ERROR: Type error in application
*** expression : ['a','b','c'] : ['a','b','c']
*** term : ['a','b','c']
*** type : [Char]
*** does not match : Char
Prelude> :type ['a','b','c']:[['a','b','c']]
['a','b','c'] : [['a','b','c']] :: [[Char]]
Prelude> ['a','b','c']:[['a','b','c']]
["abc", "abc"]
Prelude> :type length
length :: [a] -> Int
Prelude> length []
0
Prelude> length ['a']
1
Prelude> length [1000, 10000]
2
Prelude> length ( ['a','b','c']:[['a','b','c']])
2


----------HIGHER ORDER FUNCTION EXAMPLE


tabulate :: Float->Float->Int->(Float->Float)->[Float]
tabulate start step times f
|times <=0 = []
|otherwise = (f start):(tabulate (start+step) step (times-1) f)


Main> tabulate (-1) 0.2 11 sin
[-0.841471, -0.717356, -0.564642, -0.389418, -0.198669, -2.98023e-08,
0.198669, 0.389418, 0.564642, 0.717356, 0.841471]


Main> :type diff
diff :: Fractional a => (a -> a) -> a -> a
Main> :type (diff cos)
diff cos :: Floating a => a -> a
Main> tabulate (-1) 0.2 11 (diff cos)
[0.8412, 0.716984, 0.564218, 0.38898, 0.198126, -0.000476837, -0.199199,
-0.389874, -0.565052, -0.717699, -0.841737]


Main> let around_zero = tabulate (-1) 0.2 11 in around_zero sin
[-0.841471, -0.717356, -0.564642, -0.389418, -0.198669, -2.98023e-08,
0.198669, 0.389418, 0.564642, 0.717356, 0.841471]

nextnextupuppreviouspreviouscontentscontents
Next:FunktionsdefinitionenUp:Grundlegende SprachelementePrevious:Typen
Ronald Blaschke
1998-04-19