www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

constructor

Gepostet:
17.02.2010 13:57

von funktion allgemeinsten typ bestimmen  
hallo könnte mir jemand folgende aufgabe erklären?

gegeben ist:
t2 = (\x y z -> x(z));

also eine funktion t2 die eine anonyme funktion benützt.
jetzt muss man den alltemeinsten typ dafür bestimmen.
ich komme da nicht so ganz klar mit der anonymen fkt.

die lösung der aufgabe:

-- t2::(a -> b) -> c -> a -> b

wie geht man das am besten an?
Zum Seitenanfang    
 
Siracusa

Gepostet:
17.02.2010 18:38

   
Hallo,

vielleicht wird es verständlicher, wenn man die Funktion ohne Lambda-Abstraktion schreibt:
t2 x y z = x(z)

Die Klammern kann man in Haskell auch weglassen, d.h. t2 x y z = x z geht auch.

Die Funktion bekommt also schonmal drei Argumente und liefert ein Ergebnis, der Typ sieht bisher also so aus:
t2 :: ? -> ? -> ? -> ?

Dann wird der zweite Parameter überhaupt gar nicht auf der rechten Seite benutzt, es ist also völlig egal welchen Typ er hat. Nennen wir den beliebigen Typ jetzt mal c (die Namen der Typparameter sind völlig egal, könnte man jetzt auch blub nennen):
t2 :: ? -> c -> ? -> ?

Weiter sehen wir, dass der dritte Parameter auf der rechten Seite als Argument auf den ersten Parameter angewendet wird, d.h der erste Parameter ist selbst wieder eine Funktion mit einem Parameter:
t2 :: (? -> ?) -> c -> ? -> ?

Der dritte Parameter von t2 wird zum ersten Parameter von x, demnach müssen beide auch den gleichen Typ haben. Da dieser nicht weiter eingeschränkt wird, hat er wieder beliebigen Typ:
t2 :: (a -> ?) -> c -> a -> ?

Jetzt fehlt noch der Ergebnistyp von t2, der ja direkt aus dem Ergebnis von x z hervorgeht und somit direkt aus dem Ergebnistyp von x:
t2 :: (a -> b) -> c -> a -> b

Und fertig ist der allgemeinste Typ. War jetzt hoffentlich nicht zu verwirrend. ;-)


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
constructor

Gepostet:
22.02.2010 21:52

   
Dankeschön, das war mir wirklich eine super hilfe :)

ich übe das gelernte gerade bei einem anderen, schwierigerem Beispiel

die funktion lautet diesmal t2 = (\x -> \y -> (x (y x), x, y))
habe versucht das wieder ohne lamda abstraktion hinzuschreiben:

die erste anonyme fkt aufgelöst:
t2 x = \y -> (x (y x), x, y)

dann die zweite anonyme fkt aufgelöst:
t2 x y = (x (y x), x, y)

kann man das so machen?
dann steck ich bei dem problem, dass ich nicht weiß wie ich mit den beistrichen umgehen soll. Die weißen ja auf Tupel hin oder?
Wäre nochmal dankbar wenn du mir hier auf die sprünge helfen könntest...


Zum Seitenanfang    
 
Siracusa

Gepostet:
23.02.2010 04:59

   
Hi,

ja, die Funktion ist schon etwas kniffliger. Die Auflösung ist soweit richtig. Und die Kommata konstruieren tatsächlich Tupel, z.B. hat (1, "abc") den Typ (Int, String). Aus 2 oder mehr Werten wird also wieder ein neuer Wert mit einem neuen Typ konstruiert. Wichtig dabei ist, dass verschieden lange Tupel nicht den gleichen Typ haben, sondern völlig verschiedene Typen sind. Bspw. würden (a,b) und (c,d,e) beim Typabgleich scheitern, egal welche Typen man für a...e einsetzt. Dagegen könnte man (gleich lange) geschachtelte Tupel wiederum abgleichen: (a,b) und (c, (d,e,f)) ergibt a=c und b=(d,e,f).


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
constructor

Gepostet:
23.02.2010 13:10

   
nagut dann will ich mal anfagnen :)

t2 x y = (x (y x), x, y)
ist eine funktion die zwei parameter nimmt und etwas zurückliefert:

t2 :: ? -> ? -> ?

das ergebnis ist ein dreier tupel wir sehen, dass x das argument von y ist also ist y eine funktion.

t2 :: ? -> (? -> ?) -> ?

x scheint auch eine funktionzu sein weil sie ja (y x) als parameter nimmt.

t2 :: (? -> ?) -> (? -> ?) -> ?

also zweif unktionen die irgend ein ergebnis liefern

t2 :: (? -> ?) -> (? -> ?) -> ?

ab hier bin ich dann schon sehr unsicher:

y nimmt ja als argument x ....x ist aber wie wir gesehen haben eine fkt:
also muss ich statt der zweiten funktoin eine funktion schreiben die einen parameter nimmt (kann ich y x als (( ? -> ?) -> ?) aufschreiben?)

t2 :: (? -> ?) -> ((? -> ?) -> ?)) -> ?


als ergebnistyp haben wir ein dreiertupel:
t2 :: (? -> ?) -> ((? -> ?) -> ?)) -> (?,?,?)

das wärs dann mit der struktur... mit der funktion y bin ich mir sehr unsicher ob ich richtig argumentiert habe.????

Habe auch hier die angebliche Lösung:

-- t2 :: (a -> b) -> ((a -> b) -> a) -> (b,a -> b,(a -> b) -> a)

wie man aber genau drauf kommt weiß ich nicht....
Zum Seitenanfang    
 
Siracusa

Gepostet:
23.02.2010 18:43

   
Hallo,

bis hierhin war alles korrekt: t2 :: (? -> ?) -> ((? -> ?) -> ?) -> (?,?,?)

x nimmt einen Parameter und gibt einen Wert zurück, der nicht weiter eingeschränkt wird. Der Ergebnistyp von x ist also a.
t2 :: (? -> a) -> ((? -> ?) -> ?) -> (?,?,?)

Da x als Parameter von y verwendet wird, muss da natürlich auch der gleiche Ergebniswert stehen.
t2 :: (? -> a) -> ((? -> a) -> ?) -> (?,?,?)

Der Ergebnistyp von y wird auch nicht weiter eingeschränkt, muss aber der selbe sein, wie der erste Parameter von x, da y dort ja verwendet wird.
t2 :: (b -> a) -> ((? -> a) -> b) -> (?,?,?)

Dadurch ergibt sich wiederum der vollständige Typ von y, da der erste Parameter ja der gleiche Typ wie x ist.
t2 :: (b -> a) -> ((b -> a) -> b) -> (?,?,?)

Die Typen im Tupel sind nun einfach zu ergänzen, denn die entsprechen ja der Reihenfolge nach dem Ergebnistyp von x, dem Typ von x selbst und dem Typ von y selbst.
t2 :: (b -> a) -> ((b -> a) -> b) -> ( a, (b -> a), ((b -> a) -> b) )

Und wie du siehst, kommt bis auf Umbenennung der Typvariablen das gleiche Ergebnis raus. In der Praxis musst du solche Typabgleiche aber ohnehin nicht von Hand machen, da befragst du entweder den Haskell-Interpreter, oder der Typ ergibt sich automatisch anhand der Funktionsdefinition.


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
constructor

Gepostet:
19.06.2010 16:29

   
Hallo ich bins wieder, und schon wieder überfordert mit so einer Aufgabe:

diesmal geht es um t = (\x -> \y -> (x.y.x))

Also der . operator ist eine setzt die funktionen x und y zusammen ok.

ich fange wie gewohnt an und mache aus der funktion eine leichter lesbare form.

t x y = (x.y.x)

somit hätte ich am anfang mal:
? -> ? -> ?

x ist eine funktion

(?-> ?) -> ? -> ?

y ist eine funktion

(? -> ?) -> (? -> ?) -> ?

stimmt das soweit? Wie geht es hier dann weiter? das mit dem . irritiert mich ...

viele grüße


t :: (a -> b) -> (b -> a) -> a -> b
Zum Seitenanfang    
 
Siracusa

Gepostet:
20.06.2010 02:01

   
Hallo,

t gibt dir tatsächlich erstmal nicht mehr Informationen als
t :: ? -> ? -> ?

dazu
(.) :: (b -> c) -> (a -> b) -> (a -> c)

Wenn man erstmal nur einen Teilausdruck von t x y = x.(y.x) betrachtet, nämlich (y.x) == (.) y x, und das mit dem Typ von (.) abgleicht, kommt man auf
y :: b -> c; x :: a -> b; (y.x) :: a -> c

Jetzt betrachten wir den gesamten Ausdruck x.(y.x) == (.) x (y.x), dazu wird nochmal der Typ von (.) angesetzt, diesmal aber mit Strichen an den Variablen, damit man sie von den eben benutzten Variablen unterscheiden kann. Da der gesamte Ausdruck wieder den Punkt benutzt, sind die beiden Parameter für (.) diesmal x und (y.x). Für die beiden Parameter werden jetzt gleich die oben ermittelten Typen eingesetzt:
(.) :: (b' -> c') -> (a' -> b') -> (a' -> c')
x.(y.x) :: (a -> b) -> (a -> c) -> ??

Wenn man nun versucht diese beiden Signaturen zu unifizieren, kommt man auf die folgenden Schlussfolgerungen:
1.) b' == a und b' == c, daraus folgt dass a == c
2.) a' == a und c' == b, also ist ?? == a -> b, was genau dem Typ von t x y = x.(y.x) entspricht

Alle diese Informationen zusammen führen zu den Typen
x :: a -> b; y :: b -> a; t x y = a -> b

und insgesamt t :: (a -> b) -> (b -> a) -> (a -> b) was genau deinem Typ oben entspricht :-)


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
constructor

Gepostet:
21.06.2010 17:41

   
> dazu
> (.) :: (b -> c) -> (a -> b) -> (a -> c)

ist diese zeile aus t :: ? -> ? -> ? erstandenen? wie das?

> Wenn man erstmal nur einen Teilausdruck von t x y = x.(y.x) betrachtet, nämlich (y.x) == (.) y x, und das mit dem Typ von (.) abgleicht, kommt man auf

hm was heißt hier mit dem typ von (.) abgleichen? kann . überhaupt einen typ haben?
Zum Seitenanfang    
 
Siracusa

Gepostet:
21.06.2010 18:12

   
>> (.) :: (b -> c) -> (a -> b) -> (a -> c)
> ist diese zeile aus t :: ? -> ? -> ? erstandenen? wie das?
Nein, das ist der vordefinierte Typ von (.) aus den Standard-Bibliotheken.

> kann . überhaupt einen typ haben?

Muss sogar! (.) ist die Funktionskomposition und definiert als (f . g) x == f (g x), also erst g dann f anwenden. Der Punkt ist in Haskell eine ganz normale Funktion, wie + oder *.
Zum Seitenanfang