[haskell] Goede tutorials.

Pagina: 1
Acties:
  • 102 views sinds 30-01-2008
  • Reageer

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Omdat ik mijn horizon wat wil verbreden wil ik graag een functionele taal leren. Via de zig van ons aller grote vriend MBravenboer kwam ik terecht op de website vn haskell.

Ik erger me echter aan de kwaliteit van de tutorials. De tutorials lijken stuk voor stuk geschreven voor mensen die bekend zijn met functioneel programmeren. Daarnaast heb ik nog geen tutorial gevonden die uiteindelijk iets maakt wat je ook echt uit kan voeren. Allemaal gaan ze er van uit dat je alleen maar functies maakt. Ergens zul je toch moeten starten...:? een main functie of zo ?

Een van de eerste stukken code die genoemd worden in de tutorial op de site van haskell zelf is het volgende:
With this example we have defined a type sufciently rich to allow dening some interesting (recursive) functions that use it. For example, suppose we wish to define a function fringe that returns a list of all the elements in the leaves of a tree from left to right. It's usually helpful to write down the type of new functions first; in this case we see that the type should be Tree a -> [a].
That is, fringe is a polymorphic function that, for any type a, maps trees of a into lists of a. A suitable definition follows:
code:
1
2
3
fringe :: Tree a -> [a]
fringe (Leaf x) = [x]
fringe (Branch left right) = fringe left ++ fringe right
Ik snap niet wat hier nu gebeurt. De tutorial gaat er niet verder op in...
De eerste regel is een type beschrijving... Hoewel ik het niet helemaal begrijp kan ik daar nog bij mee komen.
De tweede regel definieerd dat de fringe van en blad gelijk is aan de array van dat blad of zo?
De derde regel legt uit hoe de takken afgehandeld moeten worden...
Klop dit een beetje?

Wat doet de bovenstaande code? retourneert íe in pre-order of in postorder? Hoe had ik dat kunnen zien?
Is tree in haskell een standaardtype, of is dat (impliciet) voor deze tutorial in elkaargesmurft?

-so many questions, so little answers-

Localhost, sweet localhost


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Ik heb niet helemaal goed gekeken:
Types can also be recursive, as in the type of binary trees:

Haskell:
1
data Tree a             = Leaf a | Branch (Tree a) (Tree a) 

Here we have defined a polymorphic binary tree type whose elements are either leaf nodes containing a value of type a, or internal nodes ("branches") containing (recursively) two sub-trees.

When reading data declarations such as this, remember again that Tree is a type constructor, whereas Branch and Leaf are data constructors. Aside from establishing a connection between these constructors, the above declaration is essentially defining the following types for Branch and Leaf:
code:
1
2
Branch                  :: Tree a -> Tree a -> Tree a
Leaf                    :: a -> Tree a

Localhost, sweet localhost


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Deze ben ik nu aan het bestuderen en ik vind het allemaal erg duidelijk uitgelegd. Ook van de uu.
www.cs.uu.nl/~jeroen/courses/fp-nl.pdf

En verder werk ik zelf met HUGS (Haskell interpreter) en dat werkt echt makkelijk. Je kan heel veel informatie te voorschijn toveren en je kan makkelijk kleine dingetjes testen.
http://www.haskell.org/hugs/

  • maartenvdv737
  • Registratie: Augustus 2000
  • Laatst online: 17-08 15:34
Hier is een documentatie van een vak dat ik vorig jaar aan de RUG heb gevolgd. Weet niet hoe ver je bent, maar misschien heb je er wat aan.

http://www.cs.rug.nl/~bakker/OrInf/bundel.pdf

Ik blijf er iig vrij nuchter onder....


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

de ++ operator die append 2 lijsten waar de meest linkerlijst dan ook links blijft staan. In dit geval zullen de elementen dus prefix erin staan (dus eerst linkertak helemaal in, voordat je de rechtertak in gaat).
Ik snap niet wat hier nu gebeurt. De tutorial gaat er niet verder op in...
De eerste regel is een type beschrijving... Hoewel ik het niet helemaal begrijp kan ik daar nog bij mee komen.
Dat klopt inderdaad. Wat je zit is dat het een functie is die een Tree mee krijgt als argument en een lijst terug stuurt.
De tweede regel definieerd dat de fringe van en blad gelijk is aan de array van dat blad of zo?
Dat klopt.
De derde regel legt uit hoe de takken afgehandeld moeten worden...
Klop dit een beetje?
Dat klopt ook :)

Probeer anders dit maar eens te schrijven mbv een procedurele aanpak, je zult dan allerlei verbanden zien. Ik heb laatst een stuk geschreven over het visitor design pattern. Een visitor design pattern is niet anders dan een slap aftreksel om met patterns te werken. Als je iets meer begrijpt van het functionele paradigma zul je het meteen begrijpen (en ook dat de meeste huidige oo implementaties hard zuigen).

Zie verder mijn signature hoe ik denk over functioneel icm oo :)

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Alarmnummer schreef op 01 oktober 2002 @ 22:41:
Deze ben ik nu aan het bestuderen en ik vind het allemaal erg duidelijk uitgelegd. Ook van de uu.
www.cs.uu.nl/~jeroen/courses/fp-nl.pdf

En verder werk ik zelf met HUGS (Haskell interpreter) en dat werkt echt makkelijk. Je kan heel veel informatie te voor schijn toveren en je kan makkelijk kleine dingetjes testen.
http://www.haskell.org/hugs/
Zo... die is beter inderdaad.
* kvdveer gaat lezen...

Localhost, sweet localhost


Verwijderd

vind de typedeclaratie van miranda mooier

fringe :: Tree num -> [num] als het bijvoorbeeld nums moeten zijn
fringe :: Tree * -> [.*] als elk type mag (zonder .)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik denk dat de haskell aanpak handiger is dan de miranda aanpak die jij in ieder geval laat zien. In haskell kan je in ieder geva nog weer uitspraken doen over die types en dat kan bij miranda dus niet.

bv. compositie van functies.
compositie::(a->b)->(b->c)->(a->c)
Je kan in haskell oa aangeven dat het return type van de 1e functie gelijk moet zijn aan argument type van de 2e functie. Dit zou met miranda niet kunnen als je alleen zou werken met *

Ik neem aan dat miranda dus ook wel met typevariablen mag werken ipv altijd die verplichte *.

[edit]
en verder kan je uit de haskell signature ook zien dat er bij een tree van het type a ook een lijst van het type a eruit komt. Het is gebruikelijk dat de * voor alles staat, dus dan zou het ook mogelijk zijn dat er bij een tree van het type a een lijst van het type b eruit komt.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Goed om te zien dat mensen via mijn signature kennis maken met boeiende technieken :) . Klik ook eens op de andere links zou ik zeggen ;) .

Het dictaat van de Universiteit Utrecht wat Alarmnummer postte is de oplossing van je probleem: dit is geschreven voor mensen met geen enkele functionele ervaring en zelfs maar heel weinig programmeerervaring in het algemeen. Je moet je hiermee heel aardig kunnen redden denk ik :) . Alles wordt hier prettig en vakkundig uitgelegd.

Veel plezier dus en vragen zijn natuurlijk altijd welkom :) . We kunnen hier wel een beetje functionaliteit gebruiken ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Die fringe functie in je vraag uitleggen is trouwens niet zo nuttig: je vragen worden allemaal veroorzaakt door het probleem dat je met je neus midden in de stof valt. Als je aan het begin begint (en dat begin heb je nu gevonden) wordt alles duidelijk.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Met het dictaat van de uu begin je ook bij het begin en je krijgt een zeer gedegen uitleg. Ik ben begonnen in een boek van Bird en ik vond het een zeer irritant boek omdat je toch alles probeerd te begrijpen (lijkt me logisch) wat er staat. En dan kom je continu tot de ontdekking dat verderop uitleg staat.

Trouwens is het wel zo handig dat je er ook iets mee gaat doen. Als je alleen in een boek zit te neuzen zul je veel problemen over het hoofd zien en onterect denken dat je de materie beheerst. Advies: veel (on)zinnige functies schrijven. Doel: beter inzicht Gevolg: Hekel aan oo ;)

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Alarmnummer: Hekel aan oo ;)
Waarom?
Hoezo ?

Niet te serieus nemen natuurlijk ;) . Althans... de eerste wel.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Deze al gezien?

http://www-105.ibm.com/de...6AD400822942?OpenDocument

Uit de inleiding:
This tutorial targets programmers of imperative languages wanting to learn about functional programming in the language Haskell. If you have programmed in languages such as C, Pascal, Fortran, C++, Java, Cobol, Ada, Perl, TCL, REXX, JavaScript, Visual Basic, or many others, you have been using an imperative paradigm. This tutorial provides a gentle introduction to the paradigm of functional programming, with specific illustrations in the Haskell 98 language.
Lijkt me wel toepasselijk.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:49
Alarmnummer schreef op 01 oktober 2002 @ 23:02:
Je kan in haskell oa aangeven dat het return type van de 1e functie gelijk moet zijn aan argument type van de 2e functie. Dit zou met miranda niet kunnen als je alleen zou werken met *

Ik neem aan dat miranda dus ook wel met typevariablen mag werken ipv altijd die verplichte *.
IIRC gebruikt een Miranda elke serie van *'s als afzondelijke parameter. Gelijke series worden dus wel aan elkaar gebonden;
code:
1
f :: * -> *

Is dus een functie van een ongespecificeerd type naar datzelfde type (en niet naar een willekeurig ANDER type). Het sterretjes is dus GEEN jokerteken, in de zin dat er elke keer weer iets nieuws voor ingevuld mag worden.

Je zou het type van een sequenctiele compositie operator bijvoorbeeld zo kunnen schrijven:
code:
1
f :: (* -> **) (** -> ***) * -> ***

Het idee is nu wel duidelijk, denk ik.

Ik weet niet precies hoe Haskell het oplost, maar in Clean kun je ook eisen stellen aan de typen die meegegeven worden. In combinaties met type classes (sets van operaties die op types uitgevoerd kunnen worden) kun je zo op een hele krachtige manier veilige generieke functies schrijven.

Ik kan bijvoorbeeld zeggen:
Clean:
1
2
3
4
5
class PlusMin a     | +, -, zero a
class MultDiv a     | *, /, one a
class Arith a       | PlusMin, MultDiv, abs, sign, ~ a 

f :: a -> a         | Arith a

Wat betekent dat functie f op elk type werkt dat van de klasse 'Arith' is, wat (indirect) betekent dat zo'n type opgeteld, afgetrokken, vermenigvuldigd, gedeeld en geinverteerd kan worden, dat het teken ervan opgevraagd kan worden en dat er een nul en een element voor gedefinieerd is.

Ik vind trouwens de schrijfwijze "f :: a -> b -> c -> d -> e" wel interessant in Haskell, ten opzichte van "f :: a b c d -> e", aangezien de eerste automatisch gelezen wordt als "f :: a -> (b -> (c -> (d -> e) ) )". Op deze manier is meteen duidelijk dat je in een functionele taal een functie gedeeltelijk kan toepassen; "f 2 3 4" is bijvoorbeeld een geldige functie van type (d -> e). (Voor de duidelijkheid, de functie applicatie is link-associatief, dus de evaluatie is equivalent aan "(((f 2) 3) 4)").

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: Ik weet niet precies hoe Haskell het oplost, maar in Clean kun je ook eisen stellen aan de typen die meegegeven worden. In combinaties met type classes (sets van operaties die op types uitgevoerd kunnen worden) kun je zo op een hele krachtige manier veilige generieke functies schrijven.
Deze methode van werken kent Haskell ook. Omdat ik Clean slechts zeer oppervlakkig ken kan ik geen goede vergelijking maken, maar het komt vrijwel hetzelfde op mij over. Haskell kent dus ook klassen en daarbij overloading van operatoren/functies over instanties van deze klasse. Je kan daarmee dus generieke functies maken over types in een bepaalde klasse.

code:
1
2
3
4
5
6
7
(+) :: Num a => a -> a -> a
_
class Num a where
  (+), (-) :: a -> a -> a
_
instance Num Int where
  (+) = primPlusInt


Hier wordt de operator + dus gedefinieerd als werkend over alle types in de klasse Num. In een concrete instantie van dit type (Int) wordt er aangegeven wat de type specifieke implementatie is.
Ik vind trouwens de schrijfwijze "f :: a -> b -> c -> d -> e" wel interessant in Haskell, ten opzichte van "f :: a b c d -> e"
Inderdaad ...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: Op deze manier is meteen duidelijk dat je in een functionele taal een functie gedeeltelijk kan toepassen.
Jij weet het natuurlijk wel, maar even voor als anderen de term tegenkomen: dit wordt ook wel currying genoemd.

Hier heb ik dit een keer heel simpel uitgelegd aan iemand de het al kende ;) .
[rml]mbravenboer in "[ algemeen] programmeer-programma's"[/rml]

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:49
Even voor de goede orde: currying is in de praktijk het opsplitsen van tuples in afzonderlijke argumenten en weer terug (uncurrying). In theorie (zoals Haskell Curry het verzonnen had) is 't het principe dat een samengesteled functie (AxB -> C) vergelijkbaar (homeomorf, als dat de goede term is, correct me if I'm wrong) is met een serie van eenvoudigere toepassingen, in de vorm: A -> B -> C.

Om verwarring te voorkomen met de curry-functies die gewoon 'bestaan' in de praktijk, noem ik het fenomeen liever partiële applicatie, wat ook goed uitdrukt wat er gebeurt.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:49
OFFTOPIC
mbravenboer schreef op 02 oktober 2002 @ 00:49:
Hier heb ik dit een keer heel simpel uitgelegd aan iemand de het al kende ;) .
[rml]mbravenboer in "[ algemeen] programmeer-programma's"[/rml]
Grappig draadje:
mbravenboer schreef op 18 januari 2002 @ 20:33:
KNIP: schermenlange uitleg over currying; zonder de term te gebruiken.
mbravenboer schreef op 18 januari 2002 @ 20:48:
Zeg dan gewoon van te voren dat je dat kent
Ik ben vast de enige die dit wel grappig vind...

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: Even voor de goede orde: currying is in de praktijk het opsplitsen van tuples in afzonderlijke argumenten en weer terug (uncurrying). In theorie (zoals Haskell Curry het verzonnen had) is 't het principe dat een samengesteled functie (AxB -> C) vergelijkbaar (homeomorf, als dat de goede term is, correct me if I'm wrong) is met een serie van eenvoudigere toepassingen, in de vorm: A -> B -> C.
Ik heb het werk van Curry niet gelezen dus ik weet niet hoe hij het precies gepresenteerd heeft.

Ik bekijk currying vooral als het simuleren van functies met meerdere parameters door functies die maar 1 parameter aannemen en dan een functie opleveren. ( rare syntax mix, maar goed: " a b c -> d " zien als " a -> (b c -> d) " en dit weer zien als " a -> (b -> (c -> d)) ". Er zijn dus in feite helemaal geen functies met meerdere parameters als een taal currying kent. Ik heb geen idee of in het oorspronkelijke werk ook gesproken werd over tuples en dergelijke. Gezien de werking van uncurrying zou je dit inderdaad wel vermoeden.

Dit is in andere woorden hetgene wat jij zegt ;) .

Currying zorgt er voor dat je een functie partieel kan parameteriseren en het is dus inderdaad niet zo netjes om het toepassen van deze partiele parameterizatie currying te noemen. Je verduidelijking lijkt mij dus zeer juist :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: Ik ben vast de enige die dit wel grappig vind...
Ik deed zo mijn best :'( . Ik kon er ook wel om lachen ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1