# Compilador Haskell de Glasgow

ghc, ordre d'ordinador que respon a la sigla de "Glasgow Haskell Compiler", en català Compilador Haskell de Glasgow, és un compilador nadiu de codi lliure per al llenguatge de programació funcional Haskell, el qual va ser originalment desenvolupat a la universitat de Glasgow per Simon Peyton Jones i Simon Marlow. El desenvolupament continua actualment sota l'auspici del Departament d'Investigació de Microsoft (Microsoft Research), al Regne unit on treballa Peyton Jones. GHC ha pres humorísticament el sobrenom "Glorious Haskell Compiler".
El nom ghc segueix el costum antic d'anomenar les ordres amb un identificador curt d'una a tres lletres, on la 'c' designa compilador, la 'h' designa el llenguatge i la primera lletra, la ciutat de la universitat que el desenvolupà originàriament (com també ho fa mmc: "Compilador Mercury de Melbourne", o bé yhc:"Compilador Haskell de York" o bé uhc:"Compilador Haskell d'Utrecht").
El compilador també està escrit en Haskell (una tècnica coneguda com a bootstrapping), però el nucli de sistema per a Haskell està escrit en C i una adaptació del C-- (versió de C, no per a l'ús humà sinó específica per a sortida de compiladors, com a interfície independent del maquinari) referida com a Cmm en el codi del compilador. L'última versió del compilador compleix amb l'estàndard més nou del llenguatge, que és, ara per ara, el Haskell 2010. GHC està disponible per a moltes plataformes, incloent Windows i la majoria de sistemes Unix (com les diferents distribucions de GNU/Linux), Mac OS X i la majoria d'arquitectures de processador.
Aquest incloïa, fins a la versió 6.10.x, la majoria d'extensions al Haskell estàndard, fins i tot la biblioteca STM, que serveix per fer transaccions atòmiques (o tot o no res) de dades compartides entre diferents fils d'execució.
A partir de GHC 6.12 les biblioteques ja no venen amb el compilador sinó que es distribueixen en edicions diferides, dins la Plataforma Haskell ("The Haskell Platform"). La corresponent a GHC 6.12.1 ja està disponible. Entre altres millores, suporta tractament d'entrada/sortida per a caràcters no anglosaxons, segons la codificació del sistema subjacent

## HaskellStack subordina GHC

Stackage és un rebost que per cada versió de GHC guarda instantànies d'un conjunt de biblioteques compatibles amb compilació verificada, evitant la problemàtica de seleccionar per cada biblioteca una versió que encaixi en els requeriments de les restants.
HaskellStack (2015) possibilita el desenvolupament multiversió respecte de GHC, i descarrega automàticament la versió de GHC corresponent al rebost Stackage més recent que inclogui les dependències (biblioteques) d'una aplicació si hi ha fitxer de projecte .cabal al directori, proporcionant una eina que subordina i encapsula diverses versions de GHC i dels rebostos per al desenvolupament d'aplicacions en capsa de proves (Sandbox).
També proporciona un conjunt de plantilles d'aplicacions (comanda: stack templates) per engegar projectes nous (stack new projecte plantilla).

## Biblioteques estàndard i correspondències de versions

Biblioteques de la darrera versió.
Normalment la propietat "since version X.X.X.X" de la doc. de les funcions ofereix la versió inicial de la biblioteca on es van definir.
Per saber quina versió mínima de GHC suporta una biblioteca estàndard, cal consultar les taules.
* taula de versions corresp. a GHC de 6.6 a 7.2
* taula de versions més recents. Es pot consultar versions anteriors al llistat d'actualitzacions de la pàg.

## Compilar codi antic Haskell98 amb GHC

Per compilar projectes antics en Haskell98 cal tenir en compte que
* el llenguatge per defecte ja no és el mateix (ara és Haskell2010), caldrà afegir al fitxer de projecte (.cabal):
* especificar la biblioteca haskell98 a les dependències
Si no fa servir excepcions, potser en tindreu prou amb els mòduls de la biblio haskell98
Si fa servir excepcions caldrà incloure el paquet base, i desambiguar, a les importacions, la biblioteca d'origen d'alguns mòduls Prelude, Numeric, ... presents a totes dues, com s'explica més avall.
* el sistema d'excepcions ja no és el mateix.
   * Haskell98 agrupa les excepcions en un tipus Exception, unió discriminada dels diferents tipus d'excepcions. La pega és que és un grup tancat.
   * Haskell2010 modela les excepcions en una interfície, permetent caracteritzar com a excepcions, diferents tipus on l'usuari pot especificar els camps que convingui, requerint que han d'implementar les interfícies de les classes de tipus Exception, Show i Data.Typeable.
      * La implementació de la classe Exception (del H2010) es pot derivar automàticament si el tipus implementa Show, afegint la derivació de la classe Data.Typeable i esmentant l'extensió de llenguatge DeriveDataTypeable.
      * Hi ha un tipus genèric per recollir les excepcions (del H2010) no tractades, SomeException definit de manera existencial amb l'excepció com a component.
Exemple de tractament d'excepcions al H98 i H2010 aquí.
Les excepcions antigues, des de GHC 6.10.1 van passar al mòdul Control.OldException del paquet base, s'hi van conservar fins a la versió 7.4.2 i ha estat eliminat a la versió GHC-7.6.1.
Primer de tot cal descarregar el compilador de GHC-7.4.2, l'últim que conté el mòdul Control.OldException, configurar i instal·lar, en una carpeta de l'usuari (subdir. de $HOME):
* Caldrà reanomenar les importacions de Exception i també Control.Exception
* Després, en compilar un mòdul H98 apareix un error respecte el Prelude (mòdul de predefinits):
Una manera de desambiguar-ho és explicitant a cada mòdul l'origen del Prelude desitjat.

## Gestió de memòria

Vegeu doc. GHC compila per defecte amb memòria dinàmica il·limitada. Per establir-ne límits vegeu el senyal de compilació -M. Disposa d'un recollidor de memòria brossa generacional (per defecte dues gen.), amb control d'envelliment (nombre de recol·leccions abans de passar a la generació següent) de dos passos per generació.
L'allotjament es fa dins de blocs reutilitzables, partions d'un megabloc que és el tros que es reclama al sistema quan cal i que només li retornen en havent acabat.

### Megabloc

    bloc d'un megabyte, que l'allotjador de memòria demana de cop.

### Capability

    fil d'execució lligat a un del sistema, un per cada processador elemental, sobre els quals s'executen els fils d'execució lleugers del planificador del Run Time System multiprocessador (quan es fa servir l'opció -threaded).

### Nursery (maternitat)

    zona d'allotjament de dades noves (una per capability/P.E.), del recollidor de memòria brossa generacional.
A l'inici les dades s'allotgen a la maternitat (ang:nursery) (conjunt fix de blocs) i se'n disposa d'una per capability. després passen a la generació 0, i següents tantes com s'estableixi a les opcions de l'intèrpret d'ordres per al RunTimeSystem.
Per la generació més vella, es pot triar el sistema de recollida de la brossa, entre el mètode de Cheney (aturar la recollida i copiar dades a un espai net) per defecte i el mètode de compactació que estalvia espai però és més lent. Les altres generacions fan servir el mètode de Cheney.
* Per forçar la recollida de brossa quan convingui: System.Mem.performGC
* Referències dèbils (ang:weak pointer) per a taules de memoïtzació i també per a MVar's (Mutable variable) amb mkWeakMVar.

## Fent servir biblioteques de relligat dinàmic

A partir de GHC >= 6.12 Cal que GHC s'hagi compilat amb ./configure --enable-shared

## Paral·lelisme

Novetats al bloc butlletí "Parallel Haskell Digest"

### Paral·lelisme de tasques
#### Primitives de paral·lelisme - Compilació per a processadors multicor

Vegeu-ho a Haskell concurrent#Primitives de paral·lelisme - Compilació per a processadors multicor

#### Futurs
##### Encadenament de càlculs asíncrons - la mònada Par

Vegeu-ho a Haskell concurrent#Encadenament de càlculs asíncrons - la mònada Par
El paquet meta-par ofereix una versió de la mònada Par per compartir recursos de hardware amb un planificador de tasques SMP.

##### Paral·lelisme en operacions IO - El functor aplicatiu Concurrently

Vegeu-ho a Haskell concurrent#Operacions d'Entrada/Sortida asíncrones i simultànies

### Paral·lelisme de dades
#### Vectors pluridimensionals de procés paral·lel (Regular parallel arrays)

Un primer nivell de tractament paral·lel s'ofereix mitjançant el paquet Repa ("Regular parallel arrays") de tractament en paral·lel de vectors pluridimensionals. Exemple més avall.

#### Data Parallel Haskell

GHC implementa el, més complex, paral·lelisme de dades niuat, trad. de "Nested Data Parallelism" basat en treballs de Guy E. Blelloch.
Per a proves cal instal·lar el paquet dph-examples.
Cal fixar-se en la versió instal·lada (diferent segons la versió de GHC) i descarregar-ne les fonts per investigar.
Per desenvolupar-hi cal tenir en compte que...
* Cal separar les operacions per mòduls segons si són o no vectoritzades
* A la interfície el tipus ha de ser (PArray t)
* El tipus vector ([: t :]) és NO-polimòrfic i cal especificar el tipus de l'element, com ara [: Double :], les operacions sobre els tipus primitius no estan sobrecarregades i per cada tipus cal importar-ne el mòdul d'operacions corresponent (per ex.: Data.Array.Parallel.Prelude.Double).
Vegeu exemple més avall.

#### SIMD - Single Instruction, Multiple Data - Ús de les instruccions de CPU vectoritzades

Aprofitament de les instruccions de dades vectoritzades dels processadors (MMX, 3DNow!, SSE, Altivec, AVX, ...) per al procés a CPU de corrents de dades multimèdia.
Tipus i operacions primitius SIMD a GHC.Prim.
Pàg. inicial sobre SIMD a GHC (Hi ha una branca de GHC per a desenvolupament en SIMD, però els paquets esmentats més avall i l'exemple funcionen en versions estàndard de GHC utilitzant el rerefons de compilació LLVM).
Paquets d'interfície SIMD: simd, primitive-simd.
Exemple amb dades vectoritzades de 4 Floats (4x32 bits), per a un ordinador amb SIMD sse2 de 128 bits (Pentium 4 o posterior). Compilat amb GHC v. 7.10.1. Requereix l'ús del rerefons de compilació LLVM (compilar amb l'opció -fllvm).
dona:

#### Paral·lelisme GPGPU

* Per a targetes gràfiques amb capacitat GPGPU de Nvidia o AMD-ATI, o bé sobre CPU's multicor de AMD o bé Intel via OpenCL
En l'execució de rutines sobre vectors de dades, ús de la GPU per l'execució simultània del nucli d'iteració sobre els elements dels paràmetres vectors, repartint automàticament valors del cursor (que indexa els paràmetres vectors) als diferents processadors elementals.
* Biblioteca Accelerate amb suport per a rerefons CUDA, OpenCL i RePa (per a CPUs), i genera nuclis (d'iteracions en paral·lel) per a GPU/CPU partint d'un llenguatge incrustat (EDSL) en Haskell. La biblioteca Accelerate va ser desenvolupada a la Universitat de Nova Gal·les del Sud (Austràlia) amb els auspicis de NVIDIA, desenvolupant inicialment per a dispositius NVIDIA-CUDA.
* Biblio. OpenCLWrappers facilita l'ús de lligams amb biblioteques externes que implementin l'estàndard OpenCL, article: OpenCL from Haskell
* Simultanejant càrregues de treball en CPU i GPU. Vegeu "How to write hybrid CPU/GPU programs with Haskell".

##### Exemple GPGPU d'ús de la biblioteca Accelerate

* Mòdul principal amb intèrpret de simulació del llenguatge incrustat (EDSL: "embedded domain specific language").
* Mòduls per al paral·lelisme a GPUs
   * RerefonsCUDA de NVIDIA. Requereix tenir instal·lat el compilador NVCC del ToolKit de NVIDIA.
   * Rerefons OpenCL de HIPERFIT. Cal tenir instal·lat el kit de desenvolupament (SDK) del fabricant de la GPU. L'estàndard OpenCL està implementat tant per NVIDIA com per AMD-ATI, però AMD a més d'implementar-lo en dispositius GPU, tracta la CPU multicor com un altre dispositiu de paral·lelisme.
   * Rerefons OpenCL basat en el llenguatge per al paral·lelisme Icc-Cilk de Intel.
* Mòduls per al paral·lelisme a CPUs multicor
   * Rerefons biblioteca RePa (Regular Parallel Arrays).
   * Rerefons via LLVM.
La versió per a OpenCL és al GitHub i el funcionament bàsic és idèntic.
Cal compilar amb la versió multi-tasca (opció -threaded) del RunTimeSystem

## Concurrència

* MVar's - Mutable/Mailbox Variable—variables protegides, aprofitant la concurrència basada en bústies d'un sol element.
* forkIO / forkOS
* Software Transactional Memory
* Futurs—Encadenament de càlculs asíncrons - la mònada Par
* Operacions d'Entrada/Sortida asíncrones i simultànies
* Cloud Haskell (computació distribuïda, a l'estil del sistema d'actors distribuïts de l'Erlang)
* Biblioteca Actor
* Communicating Haskell Processes (CSP)
Vegeu Haskell concurrent.

## Metaprogramació - Template Haskell

Extensió de GHC que permet l'anàlisi i generació de codi o bé Haskell o bé a expressions del tipus algebraic de l'arbre d'operacions (AST) d'un programa, com els generats internament pel compilador de Haskell.

### Avaluació en temps de compilació

El prefix "$" a un terme o bé a una expressió entre parèntesis, $terme o bé $(expr), s'anomena crida splice o d'inserció, i vol dir que cal avaluar l'expressió en temps de compilació i substituir-la, en el codi, pel seu valor. Exemple: #Punts de control al codi amb Loch-TH

### Quasi-Quotations (Plantilles per a gramàtiques DSL)

Construcció que s'avalua en temps de compilació, que permet incrustar texts convertibles a codi, escrits en gramàtiques anomenades "DSL" (Domain Specific Language), específiques per a una temàtica o domini d'aplicació, generant, per metaprogramació, expressions inter-operables amb les del mòdul que l'allotja, per exemple, plantilles HTML amb interpolació d'expressions vàlides en l'àmbit d'avaluació de la plantilla.

#### Sintaxi

    Les acotacions QuasiQuotation utilitzen una sintaxi anomenada Claus d'Oxford [|... |] o bé [prefix|... |] on el nom del prefix indica el registre que aporta els traductors del text acotat per les claus.

#### Context

    Una acotació QuasiQuotation pot descriure, segons el lloc on s'utilitza, una expressió, o bé un patró, o bé un tipus, o bé una llista de declaracions a nivell de mòdul, i, per traduir-la, s'utilitzarà el traductor corresponent al context, component del tipus descrit tot seguit.

#### Tipus

    Un tipus quasiQuoter es defineix com un registre amb traductors opcionals per cadascun dels 4 possibles contextos en què es pretengui inserir, assignant als altres el valor undefined.
    La seva definició ha d'aportar funcions per la traducció del text a expressions del llenguatge Template Haskell que incorpora combinadors per generar clàusules de codi Haskell (metaprogramació).

#### Exemple senzill: document tot seguit

Traductor simple per incloure textos multilínia en expressions (estil hereDoc o document-tot-seguit), com a literals, amb la funció stringE de T.H.
* les funcions de traducció per als contextos que no interessen es deixen undefined.
* l'ús i la definició han d'estar en mòduls separats.

#### Exemple: Incrustació de HTML amb interpolació d'expressions

De les biblioteques del Yesod.
La plantilla shamlet tradueix, a expressions del Template Haskell, un llenguatge de marques afegint automàticament les marques de tancament segons el sagnat.
Permet la interpolació d'expressions Haskell delimitades amb claus prefixades per un caràcter que determina la funcionalitat.
* Les claus "#{" ... "}" inclouen expressions avaluables quin tipus resultant ha de ser convertible implementant la classe Text.Blaze.ToMarkup.
* Les claus "^{" ... "}" permeten la inclusió per referència d'altres sub-plantilles de tipus coincident amb la que les allotja.

## Facilitats per l'optimització de fusió

En aplicar una composició sobre una estructura, per ex., (reducció. filtre p'. map f. filtre p).
Malgrat que, en ser un llenguatge d'avaluació tardana, no hi ha la problemàtica de la desforestació, hi ha propostes per fusionar-ne les iteracions.
L'ús de la pragma RULES Arxivat 2009-04-22 a Wayback Machine. permet que el compilador, en fase de pre-procés, refaci (reescrigui) operacions de composició.

### Stream fusion

Fusió de bucles en la composició d'operacions sobre estructures mitjançant la conversió de l'estructura en un corrent de dades (ang: Stream) i especificant l'operació per cada element del corrent.
El corrent incorpora la possibilitat de tenir elements sense dades, a conseqüència del filtratge.
Les funcions com ara els filtres s'han d'aplicar començant per l'operació de conversió stream sobre l'estructura, que la converteix en corrent de dades, i acabant per la inversa unstream.
En la composició de funcions, l'aparició juxtaposada de les conversions unstream al final d'una funció amb la inversa stream de l'inici de la següent és eliminada pel compilador mitjançant pragmes RULES aportades per la implementació.
Vegeu biblioteca Stream-fusion al rebost Hackage

## Referència ràpida de la biblioteca

Vegeu l'API del GHC i la de la plataforma Haskell.

### contenidors

Vegeu ref.

#### Recordatori d'algunes operacions

    S'esmenten les ops. ometent el paràm. de l'estructura sobre la qual s'aplica (Col·lecció -> Col·lecció). Si l'estructura va primer, l'operació s'esmenta en forma d'aplicació parcial infix (`op` p2 p3..). Cas de consultes o bé resultats opcionals, s'especifica ocasionalment el tipus del retorn. Respecte als tipus de les funcions, consulteu les refs.

#### notes
##### llistes amb optimització de fusió

* el paquet stream-fusion aporta llistes amb funcions fusionables pel mètode stream fusion.

##### conjunts i diccionaris

* Set ε i Map κ ε del paquet "containers" implementen conjunts i diccionaris basats en arbres de cerca binària balancejats amb cost de cerca O(log n).
* IntSet i IntMap ε també de "containers" implementen Set i Map sobre el domini Int amb implementació basada en arbres de prefix (Tries) sobre la seqüència de bits amb cost de cerca, com a màxim el nombre de bits del tipus Int.
* el paquet hashmap aporta una implementació de conjunts i diccionaris basada en IntSet i IntMap de containers, que requereix una aplicació del domini de les claus al tipus Int (funció resum (de hash en anglès) classe Hashable) i desant al conjunt/diccionari o bé un sol element/parell o bé, en en cas de col·lisions, un cistell dels elements/parells quines claus col·lideixen, implementat com a Set/Map del paquet containers. El paquet hashmap ha quedat desaconsellat en favor del paquet unordered-containers.
* el paquet unordered-containers implementa conjunts i diccionaris (HashSet i HashMap) quines claus han d'implementar una funció resum (classe Hashable) però no cal que implementin Ord (ordenable). El cistell de col·lisions en té prou amb la implementació de Eq per distingir-les.

##### seqüències finites de dos caps, amb accés més ràpid que les llistes

* Seq ε de Data.Sequence implementa seqüències finites amb dos caps (ang:double ended queue) i accés constant O(1) en afegir i recuperar per ambdós costats. viewl proporciona la vista per l'esquerra i viewr la de la dreta.
    Cost d'accés aleatori inferior a les llistes: O(log(min(i,n-i))) per a l'accés indexat;
    Cost de la concatenació: O(log(min(n1,n2)));
    Cost de la consulta de llargària O(1). Avantatge sobre les llistes (on és O(n)) per prevenir l'accés indexat fora de rang.

##### vectors pluridimensionals

* Amb vector fem referència a seqüències d'accés aleatori (accés a qualsevol element amb cost constant O(1))
* El tipus Array shape ε del paquet Repa aporta vectors pluridimensionals d'elements no-encapsulats (unboxed) (allotjats directament)
** Els elements del Repa han d'implementar
** Els tipus dels índexs del Repa prenen una forma semblant a una pila de dimensions, i implementen la classe Shape:
   * Data.Array.Repa utilitza la terminologia dels llenguatges on l'avaluació tardana és explícita, anomenant vectors diferits (ang:delayed) les aplicacions no-avaluades, per exemple amb map, forçant-ne l'avaluació amb la funció force (com a l'OCaml) que avalua, paral·lelitzant els càlculs.
   A ghci:

##### Vectors d'alt rendiment

Vectors amb índexs enters amb base 0.
Vector ε i MVector σ ε del paquet Vector aporten vectors immutables i mudables, basats en famílies de tipus, que permeten implementacions més flexibles, i, a banda, funcions fusionables (stream fusion per la composició).
* cas d'allotjament directe dels elements: Per a vectors d'elements de tipus primitius el mòdul Data.Vector.Unboxed aporta vectors immutables i mudables d'elements no encapsulats.
* hi ha altres paquets relacionats amb funcionalitats diverses
** vector-algorithms: algorismes sobre vectors mudables MVector
** vector-binary-instances: serialització
** vector-read-instances: instància de Read
** vector-instances: instàncies de diverses classes

##### biblioteca mono-traversable de Tipus Abstractes de Dades

Les classes de la biblio estàndard requereixen que les col·leccions estiguin parametritzades amb el tipus de l'element com a variable. Això fa que no es puguin aplicar a les col·leccions monomòrfiques on el tipus de l'element és fix (ex.: Word8 a Bytestring) perquè l'aritat del tipus de la col·lecció no concorda.
El paquet mono-traversable aporta un conjunt de classes d'un sol índex, on els paràmetres de tipus dependents de les col·leccions hi son referits mitjançant tipus associats a la classe o bé famílies de tipus, aplicables tant a estructures paramètriques com monomòrfiques.
A més a més aporta instàncies dels TADs per a les estructures més utilitzades relacionant-hi les operacions.
   * MonoPointed: operacions per elevar un element a la categoria de contenidor mono amb l'element d'entrada.
   * MonoFunctor: Functor sobre contenidors mono.
   * MonoZip: operacions de combinació per posició (zips) de contenidors mono. Requereix MonoFunctor
   * MonoFoldable: Catamorfismes sobre contenidors mono.
   * MonoTraversable: Recorregut (visita) dels elements dels contenidors mono que es poden travessar seqüencialment d'esquerra a dreta, aplicant-los una funció d'efectes o avaluant-los si ja ho són.
   * NonNull: tipus per embolcallar estructures no buides i efectuar-hi amb seguretat operacions parcials que petarien en estructures buides.

###### Interfícies per l'abstracció de seqüències

   * SemiSequence: Abstracció de les seqüències no-buides amb operacions basades en Semigrups. Aporta {cons, snoc, find, sortBy, reverse, intersperse}.
   * IsSequence: Abstracció de les seqüències buidables, afegint l'element neutre a SemiSequence formant un Monoide. Requereix SemiSequence, Monoid, MonoPointed, MonoTraversable
   * Textual: TAD per a seqüències de caràcters divisibles en paraules i línies. Aporta {words, unwords, lines, unlines, toUpper, toLower, ...}
   * Utf8: TAD multiparàmetre per codificar seqüències textuals en UTF-8, parametritzat amb el tipus de l'estructura d'intercanvi no codificada.

###### Interfícies per l'abstracció de conjunts i diccionaris

   * SetContainer: TAD amb les operacions comunes als contenidors d'elements distingits per una clau. (tipus de la clau, aporta consultes de la clau {member, notMember, keys}, ops. de combinació {union, unions, difference, intersection})
   * IsSet: SetContainer quins elements són claus, (Element t) coincideix amb (ContainerKey t), amb operacions dels conjunts. Requereix SetContainer.
   * IsMap: SetContainer travessable, amb les operacions dels diccionaris. Requereix SetContainer i MonoTraversable
Els noms de mono-traversable que defineixen funcions coincidents amb les del Prelude duen el prefix "o" (onull, olength, oelem, ...) per evitar haver de desfer ambiguïtats contínuament.
provant-ho sobre instàncies de IsSequence com ara String o bé Vector de Data.Vector. Caldrà especificar els tipus de seqüències desitjats com a restricció de tipus:

##### altres biblioteques rellevants

* el paquet bytestring-trie aporta una implementació de diccionaris com a arbres de prefix (Tries) per a claus de tipus ByteString
* el paquet dlist aporta llistes per diferència que redueixen el cost de concatenació en cas d'aniuament d'expressions Vegeu ref.
* el paquet heap aporta cues amb prioritat per a seqüències d'ordenables ({Min|Max}Heap) o bé de parells (prioritat, valor) ({Min|Max}PrioHeap)
* el paquet semigroups, a partir de GHC 8.0 queda integrat al paquet base. Aporta la classe Semigroup i Data.List.NonEmpty per a llistes no buides.

#### generació

* Contenidors mono-valor d'opcionalitat o bé de dualitat resultat/error
| | | | mono-valor - generació | mono-valor - generació | mono-valor - generació |
| paquet | tipus | context | sense valor o bé error | amb valor | de llista o funció generadora |
| base | Maybe ε | | Nothing | Just x | listToMaybe llista |
| base | Either tipError ε | | Left error | Right x | |
* Seqüències d'accés lineal
| | | | seqüències - generació | seqüències - generació | seqüències - generació | seqüències - generació |
| paquet | tipus | context | buit | amb un elem. | de llista o altra estructura | anamorfismes (A → A*) |
| base | [ε] | | [ ] | [x] | ll. per comprensió cycle llista | repeat x replicate n x iterate (f::ε→ε) x unfoldr (f::acc→Maybe(ε,acc)) x |
| semigroups / base (des de GHC 8.0) | NonEmpty ε | | | x :| | nonEmpty llista :: Maybe (NonEmpty ε) cycle xs | repeat x iterate (f::ε→ε) x unfoldr (f::acc→(ε,Maybe acc)) x unfold (f::acc→(ε,Maybe acc)) x |
| containers | Seq ε | | empty | singleton x | fromList llista | |
| bytestring | ByteString -- UArray Word8 | | empty | singleton x | pack llistaDeBytes | |
| text -- ∈ H. Platform | Text -- ByteString codif. UTF16 indexat com [Word16] | | empty | singleton ch | pack string | |
| classes | classes | classes | interfície | interfície | interfície | interfície |
| base | Monoid | | mempty | | | |
Data.List.cycle dispara error si la llista era buida.
* Seqüències d'accés aleatori
| | | | vectors - generació | vectors - generació | vectors - generació |
| paquet | tipus | context | buit | amb un elem. | de llista o funció generadora -- associació = (índex, valor) |
| array | Array ι ε -- immutable amb allotj. indirecte dels elements | (Ix ι) | | | listArray (iMin, iMax) llista array (iMin, iMax) llistaD'Associacions |
| array | UArray ι ε -- immutable amb allotj. directe | (Ix ι) | | | -- via interfície IArray |
| vector (tipus Índex = Int) | Vector ε -- immutable amb allotj. directe | | empty | singleton x | fromList llista replicate n x generate llarg (f :: Índex → ε) |
| vector (tipus Índex = Int) | MVector σ ε -- mudable amb allotj. directe | | | | Vector.thaw ivector -- descongela immutable replicate n x replicateM n acció clone mvector |
| repa | multidim. Array sh ε | (Shape sh, Elt ε) | | singleton x :: Array DIM0 ε | fromList shape llista |
| | classes | interfícies | interfícies | interfícies | interfícies |
| array | IArray α ε -- immutables -- α ∈ {Array, UArray} | | | | -- cal esmentar el tipus desitjat listArray (iMin, iMax) llista :: α ι ε array (iMin, iMax) llistaD'Associacions :: α ι ε -- des de MArray MArray.freeze mArray |
| array | MArray α ε m -- mudables -- mònada IO, α ∈ {IOArray, IOUArray} -- mònada ST, α ∈ {STArray, STUArray} | (Monad m) | | | -- cal esmentar el tipus desitjat newListArray (iMin, iMax) llista :: m (α ι ε) newArray (iMin, iMax) x_inicial:: m (α ι ε) -- des d'IArray thaw iArray |
* Altres estructures
| | | | estructures - generació | estructures - generació | estructures - generació | estructures - generació |
| paquet | tipus | context | buit | amb un elem. | de llista o funció generadora -- associació = (clau, valor) | de llista ordenada -- més ràpid |
| containers | IntSet | | empty | singleton x | fromList llista | fromAscList llista |
| containers | IntMap ε | | empty | singleton clau x | fromList llistaD'Associacions | fromAscList llistaD'Associacions |
| containers | Set ε | (Ord ε) | empty | singleton x | fromList llista | fromAscList llista |
| containers | Map κ ε | (Ord κ) | empty | singleton clau x | fromList llistaD'Associacions | fromAscList llistaD'Associacions |
| unordered-containers | HashSet ε | (Hashable ε, Eq ε) | empty | singleton x | fromList llista | |
| unordered-containers | HashMap κ ε | (Hashable κ, Eq κ) | empty | singleton clau x | fromList llistaD'Associacions | |
| bytestring-trie | Trie ε | | empty | singleton bytestringClau x | fromList llistaD'Associacions | |
| containers | Tree ε | | | Node x [ ] | unfoldTree f llavor | |
| heap | {Min|Max}Heap ε -- munt d'elems. ordenables | Ord ε | empty | singleton x | fromList | fromDescList fromAscList |
| heap | {Min|Max}PrioHeap prio val -- munt de parells (prioritat, valor) | Ord prio | empty | singleton (prio,val) | -- de llista de (prio,val) fromList | -- de llista de (prio,val) fromDescList fromAscList |
* TADs de mono-traversable
| | | | TADs de mono-traversable -- generació | TADs de mono-traversable -- generació |
| paquet | tipus/classe | context | amb un elem. | de llista o funció generadora |
| mono-traversable ε ~ Element t | IsSequence t | | singleton ε | fromList |
| mono-traversable ε ~ Element t | NonNull t | | | fromNullable --resultat opcional |
| mono-traversable ε ~ Element t | MonoPointed t | | opoint ε | |
| mono-traversable ε ~ Element t | IsSet t | Eq ε | singletonSet ε | setFromList llista |
| mono-traversable ε ~ Element t | IsMap t | k ~ ContainerKey t, Eq k | singletonMap k v | mapFromList llistaDeParells |

#### consulta

| | | mono-valor - consulta | mono-valor - consulta | mono-valor - consulta | mono-valor - consulta | mono-valor - consulta | mono-valor - consulta |
| | | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) |
| tipus | context | és buit? | mida | pertinença | obtenir elem | components | altres |
| Maybe ε | | isNothing | fromEnum . isJust | (==). Just | -- encaix Nothing | Just x | maybeToList fromJust fromMaybe default | --retornant elements catMaybes llistaDeMaybes |
| Either tipError ε | | isLeft | fromEnum . isRight | (==). Right | -- encaix Left error | Right x | | --retornant elements lefts llistaDeEithers rights llistaDeEithers |
* fromJust dispara error si la Maybe era buida ; fromMaybe n'és una versió segura (amb valor per defecte per als casos sense valor).
| | | seqüències - consulta | seqüències - consulta | seqüències - consulta | seqüències - consulta | seqüències - consulta | seqüències - consulta |
| | | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) | (en vermell si parcialment definides, disparen error) |
| tipus | context | és buit? | mida | pertinença | obtenir elem | components | altres |
| [ε] | | null | length | elem x | find predicat:: Maybe ε -- encaix [ ] | (x : xs) | head tail | subsequences permutations init last |
| NonEmpty ε | | | length | elem x | uncons xs :: (ε, Maybe (NonEmpty ε)) -- encaix (x :| llista) | head tail | init last |
| Seq ε | | null | length | (=/ Nothing). (elemIndex{L|R} x) | -- encaix de viewl seq EmptyL | (x :< xseq) -- encaix de viewr seq EmptyR | (x :> xseq) | -- via Foldable | |
| ByteString -- UArray Word8 | | null | length | elem x | find predicat -- encaix de uncons byteStr Nothing | Just (x, xs) :: Maybe (Word8, ByteString) | unpack :: [Word8] head tail | init last |
| Text -- ByteString codif. UTF16 indexat com [Word16] | | null | length | elem ch | find predicat -- encaix de uncons text Nothing | Just (ch, txt) :: Maybe (Char, Text) | unpack :: [Char] head tail | init last |
| classes | interfícies | interfícies | interfícies | interfícies | interfícies | interfícies | interfícies |
| Foldable contenidor | | null | length | elem x | find predicat | toList | |
* Al mòdul Data.List head, tail, init i last disparen error si la seqüència era buida. Al mòdul Data.List.NonEmpty no, perquè les seq. són no-buides: data NonEmpty a = a :| [a]
Els errors generats per funcions definides parcialment, com ara head en seqüències buidables, tenen una depuració complicada (la crida a error no informa de la situació de la crida que incompleix la pre-condició (excepte si es compila per l'ajustatge, ang:profiling i s'executa amb opcions addicionals per la depuració), ni normalment tampoc del valor causant (ex.: (dicc `Map.!` clau) pot donar l'error "Map.!: given key is not an element in the map" perquè la implementació de Show pels paràmetres no cal), només dispara una excepció genèrica ErrorCall amb el missatge).
| | | vectors - consulta | vectors - consulta | vectors - consulta | vectors - consulta | vectors - consulta | vectors - consulta |
| tipus | context | és buit? | mida | pertinença | obtenir elem | components | altres |
| Array ι ε | (Ix ι) | | | | | bounds—límits de l'índex indices elems assocs—parells (índex, valor) | |
| Vector ε | (Eq ε) | null | length | elem x | find predicat | toList head tail | init last |
| MVector σ ε | | null | length | | | Vector.freeze --cap a Vector | |
| multidim. repa Array sh ε | (Shape sh, Elt ε) | | size . extent | | | toList toScalar -- cas de shape DIM0 extent ::(Shape sh) | |
| classes | interfícies | interfícies | interfícies | interfícies | interfícies | interfícies | interfícies |
| IArray α ε -- immutables | | | | | | bounds indices elems assocs | |
| MArray α ε m -- mudables | (Monad m) | | | | | getBounds getElems getAssocs | |
| | | estructures - consulta | estructures - consulta | estructures - consulta | estructures - consulta | estructures - consulta | estructures - consulta |
| tipus | context | és buit? | mida | pertinença | obtenir elem | components | altres |
| Set ε IntSet | | null | size | | | elems | |
| Set ε IntSet | (Ord ε) | | | member x | -- cerca aproximació lookup{LT,GT,LE,GE} x | toAscList | |
| HashSet ε | (Hashable ε, Eq ε) | null | size | member x | | toList | |
| Map κ ε IntMap ε | | null | size | | | keys keysSet elems assocs | |
| Map κ ε IntMap ε | (Ord κ) | | | member clau | (! clau) lookup clau -- :: Maybe ε -- cerca aproximació lookup{LT,GT,LE,GE} clau | toAscList | |
| HashMap κ ε | (Hashable κ, Eq κ) | null | size | member clau | (! clau) lookup clau -- :: Maybe ε lookupDefault default clau -- :: ε | keys elems toList | |
| Trie ε | | null | size | member bytestringClau | lookup bstrClau | keys elems toList | submap bstrClau |
| Tree ε | | | | | | rootLabel subForest -- llista en pre-ordre flatten | -- elems per nivells levels |
| {Min|Max}Heap ε | Ord ε | null | size | | -- encaix de view heap Nothing | Just (x, heap) :: Maybe (ε, {Min|Max}Heap ε) | toList toDescList toAscList | |
| {Min|Max}PrioHeap prio val | Ord prio | null | size | | -- encaix de view heap Nothing | Just ((pri, v), heap) :: Maybe ((prio, val), {Min|Max}PrioHeap prio val) | -- llista de (prio, val) toList toDescList toAscList | |
| | | TADs de mono-traversable -- consulta | TADs de mono-traversable -- consulta | TADs de mono-traversable -- consulta | TADs de mono-traversable -- consulta | TADs de mono-traversable -- consulta |
| tipus/classe | context | és buit? | mida | pertinença | obtenir elem | altres |
| MonoFoldable t | ε ~ Element t | onull | olength | oelem ε | | headMay lastMay |
| SemiSequence t | | | | | find predicat -- retorna :: Maybe (Element t) | |
| NonNull t | MonoFoldable t | | | | | head last |
| NonNull t | IsSequence t | | | | | tail init |
| IsSet t | ε ~ Element t | | | member ε notMember ε | | |
| IsMap t | k ~ ContainerKey t | | | member k notMember k | lookup k -- resultat opcional findWithDefault def k | |

#### actualització / transformació

| | mono-valor - actualitza/transforma | mono-valor - actualitza/transforma |
| tipus | aplicació (map) als elems. | altres |
| Maybe ε | -- via Functor | maybe default (f::ε→b) |
| Either tipError ε | -- via Functor | either (f::tipError→b) (g::ε→b) |
| classes | interfícies | interfícies |
| Functor | fmap (f::a → b) | |
| | seqüències - actualitza/transforma | seqüències - actualitza/transforma | seqüències - actualitza/transforma | seqüències - actualitza/transforma | seqüències - actualitza/transforma | seqüències - actualitza/transforma |
| | | | | transforma | transforma | transforma |
| tipus | context | afegeix | elimina | aplicació (map) als elems. | altres | transforma'n una llista |
| [ε] | | (x :) | delete x | map (f:: ε → b) mapAccum{L|R} (f::acc→x→ (acc, y)) acumIni -- amb imatge opcional Maybe.mapMaybe (f::ε→Maybe b) | nub—elimina duplicats reverse intersperse x | transpose intercalate llista |
| [ε] | Ord ε | insert x | | | sort | |
| Seq ε | | (x <|) -- a l'esquerra (|> x)—a la dreta | | mapWithIndex (f:: Int → ε → b) | reverse | |
| ByteString | | cons x -- al davant snoc x -- al darrere | | map (f:: Word8 → Word8) | reverse intersperse byte | transpose intercalate bstr |
| Text | | cons ch snoc ch | | map (f:: Char → Char) | reverse intersperse ch -- específics replace cerca subst toUpper toLower toCaseFold justifyLeft llarg ch justifyRight llarg ch center llarg ch -- retalla espais strip stripLeft stripRight | transpose intercalate txt |
| classes | interfícies | interfícies | interfícies | interfícies | interfícies | interfícies |
| Functor | | | | fmap (f::a → b) | | |
* Els tipus monomòrfics (ByteString, Text i també IntSet) no implementen Functor, que requereix tipus amb l'element com a paràmetre, altrament dit, kind * -> * (aritat del tipus == 1)
| | vectors - actualitza/transforma | vectors - actualitza/transforma | vectors - actualitza/transforma | vectors - actualitza/transforma | vectors - actualitza/transforma |
| | | | transforma | transforma |
| tipus | afegeix | actualitza | aplicació (map) | altres |
| Array ι ε | | (// llistaD'Associacions) | -- via Functor | |
| Vector ε | cons x -- pel davant snoc x -- pel darrere | | map (f:: a → b) -- amb l'índex imap (f:: Int → a → b) | reverse |
| MVector σ ε | | (`set` x) clear—desvincula refs. -- copy dst src (`copy` mvectorOrigen) (`move` mvectorOrigen) | | (`grow` n) |
| multidim. repa Array sh ε | | | map (f:: a → b) | reshape shape transpose |
| classes | interfícies | interfícies | interfícies | interfícies | interfícies |
| IArray α ε | | (// llistaD'Associacions) | amap (f::a→b) | |
| MArray α ε m | | | mapArray (f::a → b) | |
| | estructures - actualitza/transforma | estructures - actualitza/transforma | estructures - actualitza/transforma | estructures - actualitza/transforma | estructures - actualitza/transforma |
| | | | | | transforma |
| tipus | context | afegeix | elimina | actualitza | aplicació (map) als elems. |
| Set ε IntSet | (Ord ε) | insert x | delete x | insert x -- subst. l'existent | map (f:: a → b) -- cas que f conservi l'ordre, més ràpid amb mapMonotonic (f:: a → b) |
| HashSet ε | (Hashable ε, Eq ε) | insert x | delete x | insert x -- subst. l'existent | map (f:: a → b) |
| Map κ ε IntMap ε | (Ord κ) | insert clau x | delete clau | adjust (f::a→a) clau update (f::a→Maybe a) clau alter (f::Maybe a → Maybe a) clau | map (f:: a → b) mapWithKey (f:: κ → a → b) mapAccum (f:: acc → a → (acc, b)) acumIni -- mapeig a les claus amb mapKeys (f::k1 -> k2) -- si f conserva l'ordre, més ràpid amb mapKeysMonotònic (f::k1 -> k2) -- en les col·lisions de f, combina valors mapKeysWith (en_col·lisions::a->a->a) (f::k1 -> k2) |
| HashMap κ ε | (Hashable κ, Eq κ) | insert clau x | delete clau | adjust (f::a→a) clau | map (f:: a → b) mapWithKey (f:: κ → a → b) |
| Trie ε | | insert bytestringClau | delete bstrClau | adjust f bstrClau | mapBy (f:: ByteString → a → Maybe b) filterMap (f:: a → Maybe b) |
| Tree ε | | | | | -- via Functor |
| {Min|Max}Heap ε | (Ord ε) | insert x | | | |
| {Min|Max}PrioHeap prio val | (Ord prio) | insert (pri, v) | | | -- via Functor |
| | | TADs de mono-traversable -- actualitza/transforma | TADs de mono-traversable -- actualitza/transforma | TADs de mono-traversable -- actualitza/transforma | TADs de mono-traversable -- actualitza/transforma |
| tipus/classe | context | afegeix | elimina | aplicació (map) als elems. | altres |
| (ε = Element t) | | | | | |
| SemiSequence t | | cons -- pel davant snoc -- pel darrere | | | intersperse reverse sortBy (f::ε->ε->Ordering) |
| IsSequence t | Eq (Element t) | | delete ε | | |
| IsSequence t | Ord (Element t) | | | | sort |
| MonoFunctor t | | | | omap (f::ε->ε) | |
| IsSet t | (ε ~ ContainerKey t, Eq ε) | insertSet ε | deleteSet ε | | |
| IsMap t | (k ~ ContainerKey t, Eq k) | insertMap k v | deleteMap k | adjustMap f k updateMap f k alterMap f k | |
* Els tipus (Set a) i (HashSet a) no implementen Functor (#perquè els conjunts no implementen Functor).
Nota per les funcions d'actualització als diccionaris:
* adjust (f::v→v) clau dicc : actualitza el valor, si i només si clau pertany al diccionari dicc.
* update (f::v→Maybe v) clau dicc : actualitza o bé elimina, segons existeixi (isJust) la imatge de la funció f per al valor corresponent a la clau
* alter (f::Maybe v → Maybe v) clau dicc : (actualitza o bé elimina o bé insereix) si clau no existeix, la insereix amb el valor (f Nothing); altrament com update

#### accés indexat

| | | seqüències - accés indexat | seqüències - accés indexat | seqüències - accés indexat | seqüències - accés indexat | seqüències - accés indexat |
| | | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) |
| tipus | context | elem. a l'índex | cerca l'índex de l'elem. :: Maybe Int | cerca índexs ::[Int] | elimina | actualitza |
| [ε] | | (!! índx) | elemIndex x -- per valor findIndex predicat -- per predicat | elemIndices x findIndices predicat | | |
| Seq ε | | (`índex` índx) -- amb result. opcional: lookup indx (`!?` indx) | elemIndexL x -- per l'esquerra findIndexL predicat elemIndexR x --per la dreta findIndexR predicat | elemIndices{L|R} x findIndices{L|R} predicat | | adjust f índx update índx x |
| ByteString | | (`índex` índx) | elemIndex x -- pel davant elemIndexEnd x -- pel darrere findIndex predicat | elemIndices x findIndices predicat | | |
| Text | | (`índex` índx) | findIndex predicat | | | |
| | | vectors - accés indexat | vectors - accés indexat | vectors - accés indexat | vectors - accés indexat | vectors - accés indexat |
| | | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) | en color si disparen error, en marró si és previsible: domini acotat i continu: length O(1) i índex ∈ [0,length) |
| tipus | context | elem. a l'índex | cerca l'índex de l'elem. :: Maybe Int | cerca índexs | actualitza |
| Array ι ε | | (! índx) | | | |
| Vector ε | | (! índx) (!? índx) -- :: Maybe ε | elemIndex x findIndex predicat | -- retornen :: Vector Int elemIndices x findIndices predicat | |
| MVector σ ε | | (`read` indx) | | | (`write` indx x) (`swap` i j) |
| multidim. repa Array sh ε | (Shape sh, Elt ε) | (! índxMultiDim) (`índex` índxMultiDim) | | | |
| multidim. repa Array sh ε | (Shape sh, Elt ε) | (`safeIndex` índxMultiDim) | | | |
| classes | interfícies | interfícies | interfícies | interfícies | interfícies | interfícies |
| IArray α ε | | (! índx) | | | |
| MArray α ε m | (Monad m) | (`readArray` indx) | | | (`writeArray` indx x) |
| | | estructures - accés indexat (índex basat en zero sobre seq. ordenada) | estructures - accés indexat (índex basat en zero sobre seq. ordenada) | estructures - accés indexat (índex basat en zero sobre seq. ordenada) | estructures - accés indexat (índex basat en zero sobre seq. ordenada) |
| | | en color si disparen error, en marró si és previsible: domini acotat i continu: size O(1) i índex ∈ [0,size) | en color si disparen error, en marró si és previsible: domini acotat i continu: size O(1) i índex ∈ [0,size) | en color si disparen error, en marró si és previsible: domini acotat i continu: size O(1) i índex ∈ [0,size) | en color si disparen error, en marró si és previsible: domini acotat i continu: size O(1) i índex ∈ [0,size) |
| tipus | context | elem. a l'índex | cerca l'índex de l'elem. | elimina | actualitza |
| Set ε | (Ord ε) | elemAt índx retorna :: ε | findIndex valor -- :: Int lookupIndex valor -- :: Maybe Int | deleteAt índx | |
| Map κ ε | (Ord κ) | elemAt índx retorna :: (κ,ε) | findIndex clau -- :: Int lookupIndex clau -- :: Maybe Int | deleteAt índx | updateAt f índx |
* TADs de mono-traversable -- accés indexat

#### combinació

| | combina per op. associativa (semigrup) o per aparellament correlatiu (zips) | combina per op. associativa (semigrup) o per aparellament correlatiu (zips) | combina per op. associativa (semigrup) o per aparellament correlatiu (zips) | combina per op. associativa (semigrup) o per aparellament correlatiu (zips) | combina per op. associativa (semigrup) o per aparellament correlatiu (zips) |
| tipus | context | combinació associativa | combina'n una llista | combina per posició (zips) zip = zipWith (,) | desacobla llista de tuples (unzips) |
| Maybe ε | | -- via Monoid | -- via Monoid | | |
| [ε] | | (++) | concat | (`zip` llista) (`zip{3..7}` llista...) zipWith (f::a→b→c) llista1 llista2 zipWith{3..7} f llista... | unzip unzip{3..7} |
| Seq ε | | (><) | | (`zip` seq) (`zip{3..4}` seq...) zipWith (f::a→b→c) seq1 seq2 zipWith{3..4} f seq... | |
| ByteString | | append | concat | (`zip` byteStr) zipWith (f::Word8→Word8→a) byteStr1 byteStr2 | unzip |
| Text | | append | concat | (`zip` txt) zipWith (f::Char→Char→Char) txt1 txt2 | |
| Set ε IntSet | (Ord ε) | union | unions | | |
| HashSet ε | (Hashable ε, Eq ε) | union | unions | | |
| Map κ ε IntMap ε | (Ord κ) | union -- amb func. combinació unionWith (f::ε -> ε -> ε) unionWithKey (f::κ -> ε -> ε -> ε) | unions -- amb func. combinació unionsWith (f::ε -> ε -> ε) | | |
| HashMap κ ε | (Hashable κ, Eq κ) | union -- amb func. combinació unionWith (f::ε -> ε -> ε) | unions | | |
| Trie ε | | union{L|R} mergeBy (f::ε -> ε -> Maybe ε) | -- via Monoid | | |
| Tree ε | | | | | |
| {Min|Max}Heap ε | (Ord ε) | union | unions | | |
| {Min|Max}PrioHeap prio val | (Ord prio) | union | unions | | |
| Array ι ε | | | | | |
| Vector ε | | (++) | concat | (`zip` vect) (`zip{3..6}` vect) zipWith (f::a→b→c) vect1 vect2 zipWith{3..6} f vect... -- amb l'índex a la funció izipWith (f::Int→a→b→c) vect1 vect2 izipWith{3..6} f vect... | unzip unzip{3..6} |
| multidim. repa Array sh ε | | (++) append | | | |
| classes | interfícies | interfícies | interfícies | interfícies | interfícies |
| Monoid | | mappend | mconcat | | |
| IArray α ε | | | | | |
| MArray α ε m | | | | | |
| | combina com a conjunt o bé multiconjunt | combina com a conjunt o bé multiconjunt | combina com a conjunt o bé multiconjunt | combina com a conjunt o bé multiconjunt | combina com a conjunt o bé multiconjunt | combina com a conjunt o bé multiconjunt | combina com a conjunt o bé multiconjunt | combina com a conjunt o bé multiconjunt |
| tipus | context | diferència | unió | uneix-ne una llista | intersecció | està contingut | contingut estrictament | obtenir distints |
| [ε] | | (\\) -- multi | union—vegeu ref. | | intersect—multi | (`isPrefixOf` llista) (`isSuffixOf` llista) (`isInfixOf` llista) | | nub |
| Seq ε | | | | | | | | |
| ByteString | | | | | | (`isPrefixOf` byteStr) (`isSuffixOf` byteStr) (`isInfixOf` byteStr) | | |
| Text | | | | | | (`isPrefixOf` txt) (`isSuffixOf` txt) (`isInfixOf` txt) | | |
| Set ε IntSet | (Ord ε) | (\\) difference | union | unions | intersection | isSubsetOf | isProperSubsetOf | |
| HashSet ε | (Hashable ε, Eq ε) | difference | union | unions | intersection | | | |
| Map κ ε IntMap ε | (Ord κ) | (\\) difference | union | unions | intersection | isSubmapOf | isProperSubmapOf | |
| HashMap κ ε | (Hashable κ, Eq κ) | difference | union unionWith (f::ε -> ε -> ε) | unions | intersection intersectionWith (f::ε -> ε -> ε) | | | |
| Trie ε | | | unionL unionR | | | | | |
| {Min|Max}Heap ε | (Ord ε) | | union | unions | | | | |
| {Min|Max}PrioHeap prio val | (Ord prio) | | union | unions | | | | |
* TADs de mono-traversable -- combinació

#### reducció

| | plegats | plegats | plegats | plegats |
| | (en color si parcialment definides, disparen error) | (en color si parcialment definides, disparen error) | (en color si parcialment definides, disparen error) | (en color si parcialment definides, disparen error) |
| tipus | reducció | reducció | successió de plegats parcials | successió de plegats parcials |
| | per l'esquerra | per la dreta | per l'esquerra | per la dreta |
| [ε] | foldl (f::a→ε→a) inicial foldl' f ini -- estricte foldl1 (g::ε→ε→ε) -- sobre el primer elem. | foldr f ini foldr1 g | scanl f ini scanl1 g | scanr f ini scanr1 g |
| NonEmpty ε | via Foldable | via Foldable | scanl f ini scanl1 g | scanr f ini scanr1 g |
| Seq ε | via Foldable | via Foldable | scanl f ini scanl1 g | scanr f ini scanr1 g |
| classes | | | | |
| Foldable t | foldl f ini foldl' f ini -- estricte foldl1 g | foldr f ini foldr' f ini -- estricte foldr1 g | | |
* foldl1, foldr1, scanl1, scanr1: disparen error si la col·lecció era buida.
| | llistes de mono-valor - plegats especials | llistes de mono-valor - plegats especials |
| tipus | llista de contenidors | llista de contenidors |
| | retornant [a] | retornant ([a], [b]) |
| Maybe ε | catMaybes | |
| Either tipError ε | lefts rights | -- (lefts, rights): partitionEithers |
| | plegats especials | plegats especials | plegats especials | plegats especials | plegats especials | plegats especials | plegats especials | plegats especials |
| tipus | sobre booleans | s/. predicat | s/. ordre | numèrics | amb funció de projecció al tipus de l'estructura | contenidor d'estructures | contenidor de llistes | índex del menor/major |
| | ε ~ Bool | | (Ord ε / κ) | (Num ε) | | | | (Ord ε) |
| [ε] | and or | all predicat any predicat | minimum maximum | sum product | concatMap (f::a→[b]) | concat | | |
| ByteString | | all predicat any predicat | minimum maximum | | concatMap (f::Word8→ByteString) | concat | | |
| Text | | all predicat any predicat | minimum maximum | | concatMap (f::Char→Text) | concat | | |
| Vector ε | and or | all predicat any predicat | minimum maximum | sum product | concatMap (f::a → Vector b) | concat | | minIndex maxIndex |
| Set ε | -- via Foldable | -- via Foldable | findMin findMax | -- via Foldable | -- via Foldable | -- via Monoid | | |
| IntSet | | | findMin findMax | | | -- via Monoid | | |
| HashSet ε | -- via Foldable | -- via Foldable | | -- via Foldable | -- via Foldable | -- via Monoid | | |
| Map κ ε IntMap ε | -- via Foldable | -- via Foldable | -- min/max de la clau findMin findMax | -- via Foldable | -- via Foldable | -- via Monoid | | |
| HashMap κ ε | -- via Foldable | -- via Foldable | | -- via Foldable | -- via Foldable | -- via Monoid | | |
| {Min|Max}PrioHeap prio val | -- via Foldable | -- via Foldable | | -- via Foldable | -- via Foldable | -- via Monoid | | |
| classes | | | | | | | | |
| | | | | | (Monoid m) | | | |
| Foldable t | and or | all predicat any predicat | minimum maximum | sum product | foldMap (f::a→m) concatMap (f::a→[b]) | | concat | |
| Monoid t | | | | | | mconcat | | |
* minimum, maximum disparen error si la col·lecció era buida
* minIndex, maxIndex disparen error si el vector era buit
* findMin, findMax disparen error si el conjunt o diccionari eren buits
* els tipus monomòrfics (ByteString, Text, IntSet) no implementen Foldable que requereix tipus amb l'element com a paràmetre, altrament dit Kind (* -> *) (aritat del tipus == 1)
| | TADs de mono-traversable -- plegats | TADs de mono-traversable -- plegats |
| | les funcions parcials (disparen error) duen el sufix Ex | les funcions parcials (disparen error) duen el sufix Ex |
| tipus/classes | reducció | reducció |
| ε = Element t | per l'esquerra | per la dreta |
| MonoFoldable t | ofoldl' (f::a→ε→a) ini -- estricte ofoldl1Ex' (g::ε→ε→ε) -- sobre el primer elem. | ofoldr f ini ofoldr1Ex g -- sobre el primer elem. |
| NonNull t | ofoldl1' (g::ε→ε→ε) -- sobre el primer elem. | ofoldr1 g |
| | TADs de mono-traversable -- plegats especials | TADs de mono-traversable -- plegats especials | TADs de mono-traversable -- plegats especials | TADs de mono-traversable -- plegats especials | TADs de mono-traversable -- plegats especials | TADs de mono-traversable -- plegats especials | TADs de mono-traversable -- plegats especials | TADs de mono-traversable -- plegats especials |
| | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional | * sufix Ex: funcions parcials, disparen error * sufix May: resultat opcional |
| tipus/classes | sobre booleans | s/. predicat | s/. ordre | numèrics | elements monoides | amb projecció a monoide |
| ε = Element t | ε ~ Bool | | (Ord ε) | (Num ε) | (Monoid ε) | (Monoid m) |
| MonoFoldable t | oand oor | oall predicat oany predicat | minimum{May|Ex} maximum{May|Ex} | osum oproduct | oconcat | oconcatMap (f::ε -> m) |
| NonNull t | | | minimum maximum | | | |

#### partició

| | | mono-valor - filtratge |
| tipus | context | filtre |
| Maybe ε | | via MonadPlus |
| classes | | |
| MonadPlus t | | mfilter |
| | seqüències - partició | seqüències - partició | seqüències - partició | seqüències - partició | seqüències - partició | seqüències - partició | seqüències - partició |
| tipus | a l'índex | a l'índex | s/. predicat | s/. predicat | en trams d'elements consecutius equivalents | per ocurrències d'un separador | en trams de llargada fixa |
| | | :: (t,t) | | :: (t,t) | group = groupBy (==) | | |
| [ε] | take n drop n | splitAt índx | filter predicat takeWhile predicat dropWhile predicat | partition predicat span predicat break predicat | group groupBy (equiv::a→a→Bool) | | |
| Seq ε | take n drop n | splitAt índx | filter predicat takeWhile{L|R} predicat dropWhile{L|R} predicat | partition predicat span{l|r} predicat break{l|r} predicat | | | |
| ByteString | take n drop n | splitAt índx | filter predicat takeWhile predicat dropWhile predicat | partition predicat span predicat break predicat | group groupBy (equiv::Word8→Word8→Bool) | split separador splitWith predicatDelSeparador | |
| Text | take n drop n -- pel final takeEnd n dropEnd n | splitAt índx | filter predicat takeWhile predicat dropWhile predicat -- pel final takeWhileEnd predicat dropWhileEnd predicat -- ambdós extrems dropAround predicat | partition predicat span predicat break predicat | group groupBy (equiv::Char→Char→Bool) | splitOn textSeparador split predicatDelSeparador | chunksOf n |
* (span{l|r} predicat) parteix com (takeWhile{L|R} predicat, dropWhile{L|R} predicat)
* (break{l|r} predicat) equival a (span{l|r} (not. predicat))
| | vectors - partició | vectors - partició | vectors - partició | vectors - partició | vectors - partició |
| tipus | a l'índex | a l'índex | s/. predicat | s/. predicat | en funció d'un rang -- array de parells [(i, arr ! f i) | i <- [iMin..iMax] ] |
| | | | | | (Ix i, Ix j) => |
| Array ι ε | | | | | ixmap (iMin, iMax) (f::i → j) |
| Vector ε | take n drop n slice índx n | splitAt índx | filter predicat takeWhile predicat dropWhile predicat | partition predicat span predicat break predicat | |
| MVector σ ε | take n drop n slice índx n | splitAt índx | | | |
| classes | | | | | |
| IArray α ε | | | | | ixmap (iMin, iMax) (f::i → j) |
| MArray α ε m | | | | | mapIndices (iMin, iMax) (f::i → j) |
| | estructures - partició | estructures - partició | estructures - partició | estructures - partició | estructures - partició |
| tipus | context | a l'índex | en inferiors i superiors (estrictament) | s/. predicat | pel prefix |
| Set ε IntSet | (Ord ε) | | split pivot | partition predicat filter predicat | |
| HashSet ε | (Hashable ε, Eq ε) | | | filter predicat | |
| Map κ ε IntMap ε | (Ord κ) | | split clauPivot | partition predicat filter predicat | |
| HashMap κ ε | (Hashable κ, Eq κ) | | | filter predicat filterWithKey (f::clau->predicat) | |
| Trie ε | | | | | submap bytestrPrefixClau |
| Tree ε | | | | | |
| {Min|Max}Heap ε | (Ord ε) | take n drop n splitAt n | | filter predicat partition predicat takeWhile predicat dropWhile predicat span predicat break predicat | |
| {Min|Max}PrioHeap prio val | (Ord prio) | take n drop n splitAt n | | filter predicat partition predicat takeWhile predicat dropWhile predicat span predicat break predicat | |
| | TADs de mono-traversable - partició | TADs de mono-traversable - partició | TADs de mono-traversable - partició | TADs de mono-traversable - partició | TADs de mono-traversable - partició | TADs de mono-traversable - partició | TADs de mono-traversable - partició |
| tipus | context | a l'índex | a l'índex | s/. predicat | s/. predicat | en trams d'elements consecutius equivalents | per ocurrències d'un separador |
| índx ∈ Index t | | | :: (t,t) | | :: (t,t) | group = groupBy (==) | |
| IsSequence t | | take índx drop índx | splitAt índx | filter predicat takeWhile predicat dropWhile predicat | partition predicat span predicat break predicat | groupBy (equiv::a→a→Bool) | splitWhen predicat -- retorna [t] |
| IsSequence t | Eq (Element t) | | | | | group | splitElem x splitSeq xs |

#### implementació de classes

classes de la biblioteca GHC que les col·leccions implementen:
* control seqüencial:
   * Monad: encadenament d'accions funció del resultat de la precedent. Seqüencia les accions.
   * Applicative: combinació de resultats d'accions: Seqüencia només les engegades. Aplicable en paral·lelisme.
* composició no-seqüencial: Monoid
* composició seqüencial (control seqüencial amb Monoide): Alternative, MonadPlus
* mapejat no-seqüencial: Functor (Functor garanteix que l'aplicació de la composició de morfismes equival a la composició de les aplicacions dels morfismes individualment, estalviant la multiplicitat de travessaments)
* visita seqüencial (cas d'elements amb efectes o bé les imatges d'un mapeig amb una funció d'efectes): Traversable
* reducció: Foldable
* comparació de les col·leccions: Eq, Ord
* textualitzacio de les col·leccions: Show, Read
* travessament genèric de l'estructura de les col·leccions: Data, Generic
* avaluació en profunditat (a forma normal) de les col·leccions: NFData (contracció de Normal Form Data)
* serialització de les col·leccions: Binary

##### excepcions i crítiques

* els tipus monomòrfics (ByteString, Text i IntSet no poden implementar les classes Functor i Foldable, Applicative, Monad, Alternative, MonadPlus, Traversable (quines funcions estan definides per a tipus amb un paràmetre). En intentar-ho, dona l'error: Kind mis-match (l'aritat del tipus no és l'esperada). Solució paquet mono-traversable (vegeu #alternatives)
* no implementen Functor:
** Els conjunts. #perquè els conjunts no implementen Functor!

###### alternatives

** El paquet mono-traversable aporta versions genèriques de classes estàndard per a contenidors, sense l'exclusió dels tipus monomòrfics, definint l'element com una família de tipus.
    Les funcions parcials tenen versions amb sufix Ex (poden disparar excepció cridant error), o bé sufix May (resultat opcional)
| classe (context de la classe) | context del mètode | mètodes |
| MonoFunctor t | | omap (f :: Element t -> Element t) |
| MonoFoldable t | Monoid m | ofoldMap (f :: Element t -> m) |
| MonoFoldable t | | ofoldr (op :: Element t -> acc -> acc) accIni |
| MonoFoldable t | | ofoldl' (op :: acc -> Element t -> acc) accIni |
| MonoFoldable t | | onull |
| MonoFoldable t | | olength |
| MonoFoldable t | | otoList |
| MonoFoldable t | | {oall, oany} predicat |
| MonoFoldable t | | head{Ex|May}, last{Ex|May} |
| | (MonoFoldable t, Num (Element t)) | osum, oproduct |
| | (MonoFoldable t, Element t ~ Bool) | oand, oor |
| MonoFoldableMonoid t (MonoFoldable t, Monoid t) | | oconcatMap (f :: Element t -> t) |
| MonoFoldableEq t (MonoFoldable t, Eq (Element t)) | | oelem x |
| MonoFoldableEq t (MonoFoldable t, Eq (Element t)) | | onotElem x |
| MonoFoldableOrd t (MonoFoldable t, Ord (Element t)) | | {minimum|maximum}{Ex|May} |
| MonoFoldableOrd t (MonoFoldable t, Ord (Element t)) | | {minimum|maximum}By{Ex|May} (f :: Element t -> Element t -> Ordering) |
| MonoTraversable t (MonoFunctor t, MonoFoldable t) | Applicative efecte | otraverse (f :: Element t -> efecte (Element t)) |
| MonoTraversable t (MonoFunctor t, MonoFoldable t) | Monad efecte | omapM (f :: Element t -> efecte (Element t)) |
| MonoPointed t | | opoint x |

##### perquè els conjunts no implementen Functor

Perquè no mantenen la regla de la composició de morfismes dels Functors: $F(g\circ f)=F(g)\circ F(f)$ per a tot morfisme $f:X\rightarrow Y\,\!$ i $g:Y\rightarrow Z$. Vegeu Functor#Els conjunts no són Functor

##### implementacions

| | implementació de classes d'avaluació seqüencial dels elements | implementació de classes d'avaluació seqüencial dels elements | implementació de classes d'avaluació seqüencial dels elements | implementació de classes d'avaluació seqüencial dels elements | implementació de classes d'avaluació seqüencial dels elements |
| tipus | Applicative (combinador de resultats d'accions) | Alternative (applicative amb monoide) -- requereix Applicative | Monad (encadenament d'accions funció del resultat de la precedent) | MonadPlus (mònada amb monoide) --requereix Monad | Traversable (visita avaluant seqüencialment els elements si són accions o bé aplicant una funció d'efectes als elements) -- requereix Functor, Foldable |
| Maybe ε | Sí | Sí | Sí | Sí | Sí |
| Either tipError ε | Sí | No | Sí | No | des de ghc 7.8 |
| [ε] | Sí | Sí | Sí | Sí | Sí |
| Seq ε | Sí | des de ghc 7.8 | Sí | Sí | Sí |
| Array ι ε | No | No | No | No | No |
| Vector ε | Sí | Sí | Sí | Sí | Sí |
| Set ε | No | No | No | No | No |
| HashSet ε | No | No | No | No | No |
| Map κ ε IntMap ε | No | No | No | No | Sí |
| HashMap κ ε | No | No | No | No | Sí |
| Trie ε | Sí | No | Sí | No | Sí |
| Tree ε | Sí | No | Sí | No | Sí |
* Al GHC 7.10 està previst que Applicative esdevingui superclasse de Monad, i que Alternative ho sigui de MonadPlus.
* Alternative i MonadPlus inclouen implementacions que obeeixen regles diferents. Hi ha una proposta per separar cadascuna d'elles en dues classes.
   * La regla de l'element absorbent per l'esquerra (ang:Left Catch): Maybe la compleix; la Llista no
   * La propietat distributiva per l'esquerra (ang:Left Distribution): La Llista la compleix; Maybe no
| | implementació de classes | implementació de classes | implementació de classes | implementació de classes | implementació de classes | implementació de classes |
| tipus | Monoid (componible: mempty, mappend) | Functor (mapejable: fmap) | Foldable (reduïble: foldl, foldr) -- requereix Functor | Binary (serialitzable: put, get) | NFData (avaluable a Forma Normal: rnf, deepseq) | Data (que se'n pot recórrer l'estructura genèricament: gfoldl, gmapX) |
| Maybe ε | (Monoid ε) compon els elements | Sí | Sí | (Binary ε) | (NFData ε) | (Data ε) |
| Either tipError ε | No | Sí | des de ghc 7.8 | (Binary tipError, Binary ε) | (NFData tipError, NFData ε) | (Data tipError, Data ε) |
| [ε] | mappend = (++) | Sí | Sí | (Binary ε) | (NFData ε) | (Data ε) |
| Seq ε | mappend = (><) | Sí | Sí | (Binary ε) | (NFData ε) | (Data ε) |
| ByteString | mappend = append | N/A: l'aritat del tipus no concorda (Kind mis-match) | N/A: l'aritat del tipus no concorda | Sí | Sí | Sí |
| Text | mappend = append | N/A: l'aritat del tipus no concorda (Kind mis-match) | N/A: l'aritat del tipus no concorda | (-- implementable via "binary-generic") | Sí | Sí |
| Array ι ε | No | Sí | No | (Binary ι, Binary ε) | (NFData ι, NFData ε) | No |
| Vector ε | mappend = (++) | Sí | Sí | (Binary ε) -- instàncies al paquet vector-binary-instances | (NFData ε) | (Data ε) |
| Set ε | (Ord ε) mappend = union | No #perquè els conjunts no implementen Functor | Sí | (Binary ε) | (NFData ε) | (Data ε, Ord ε) |
| HashSet ε | mappend = union | No #perquè els conjunts no implementen Functor | Sí | (-- implementable via "binary-generic") | (NFData ε) | (Data ε) |
| IntSet | mappend = union | #perquè els conjunts no implementen Functor | N/A: l'aritat del tipus no concorda | Sí | Sí | Sí |
| Map κ ε IntMap ε | (Ord κ) mappend = union cas de claus coincidents es pren el valor del primer operand | Sí | Sí | (Binary ε) | (NFData κ, NFData ε) | (Data κ, Data ε, Ord κ) |
| HashMap κ ε | mappend = union | Sí | Sí | (-- implementable via "binary-generic") | (NFData κ, NFData ε) | (Data κ, Data ε) |
| Trie ε | (Monoid ε) mappend = mergeBy... cas de claus coincidents en compon els valors | Sí | Sí | (Binary ε) | No | No |
| Tree ε | No | Sí | Sí | (Binary ε) | (NFData ε) | (Data ε) |
| {Min|Max}Heap ε | mappend = union | No | No | No | No | No |
| {Min|Max}PrioHeap prio val | mappend = union | Sí | Sí | No | No | No |
| | classes requerides pels TAD de mono-traversable | classes requerides pels TAD de mono-traversable | classes requerides pels TAD de mono-traversable | classes requerides pels TAD de mono-traversable | classes requerides pels TAD de mono-traversable | classes requerides pels TAD de mono-traversable |
| TAD | Semigroup (semigrup: <>) | Monoid (componible: mempty, mappend) | MonoFunctor (mapejable: omap) | MonoFoldable (reduïble: ofoldl, ofoldr) | MonoTraversable (travessable: otraverse, omapM) | MonoPointed (generable des d'un valor: opoint -- com pure de Applicative) |
| SemiSequence -- seqs. no-buides | Sí | No | No | Sí | No | No |
| IsSequence -- seqs. buidables | Sí | Sí | Sí | Sí | Sí | Sí |
| SetContainer | Sí | Sí | No | Sí | No | No |
| IsSet | Sí | Sí | No | Sí | No | No |
| IsMap | Sí | Sí | Sí | Sí | Sí | No |
Altres classes habituals dels contenidors:
* Eq t: Compara contenidors igualables comparant els elements segons l'ordre seqüencial o bé mitjançant la conversió a llista.
* Ord t: Compara contenidors ordenables comparant els elements segons l'ordre seqüencial o bé mitjançant la conversió a llista ascendent.
* Show t: Contenidor textualitzable a String independent de la codificació de caràcters (els caràcters ASCII imprimibles (0x20 a 0x7F) tal com són, els metacaràcters (com ara '\t',..) amb el prefix '\', altres caràcters en representació numèrica, inclosos els no-anglosaxons). Per una sortida humanament llegible dels caràcters no anglosaxons, cal fer servir el paquet Text.
* Read t: Omple contenidor llegint la sortida de (Show t).
| | implementa classes | implementa classes | implementa classes | implementa classes |
| tipus | Eq (Igualable) | Ord (Ordenable) | Show (Textualitzable) --només ASCII altrament codis numèrics | Read (Llegible) --només ASCII altrament codis numèrics |
| --monomòrfics ByteString Text IntSet | Sí | Sí | Sí | Sí |
| --tipus d'aritat 1 Maybe ε [ε] Seq ε Vector ε Set ε IntMap ε | (Eq ε) | (Ord ε) | (Show ε) | (Read ε) |
| --tipus d'aritat 2 Map κ ε Either κ ε | (Eq κ, Eq ε) | (Ord κ, Ord ε) | (Show κ, Show ε) | (Read κ, Read ε) |
| --tipus amb particularitats | | | | |
| (Ix ι) => Array ι ε | (Eq ε) | (Ord ε) | (Show ι, Show ε) | No |
| Tree ε | (Eq ε) | No | (Show ε) | (Read ε) |
| (Hashable ε, Eq ε) => HashSet ε | Sí | No | (Show ε) | (Read ε) |
| (Hashable κ, Eq κ) => HashMap κ ε | (Eq ε) | No | (Show κ, Show ε) | (Read κ, Read ε) |
| (Ord ε) => {Min|Max}Heap ε | Sí | Sí | Sí | Sí |
| (Ord prio) => {Min|Max}PrioHeap prio val | Sí | Sí | Sí | Sí |

##### Implementació de Binary (serialitzable) amb binary-generic

Cal que el tipus implementi la classe Data del mòdul Data.Data que possibilita el recorregut genèric de l'estructura del tipus. Vegeu el paquet binary-generic
prova:

##### Sobrecàrrega de literals

La sobrecàrrega de literals permet associar-los a una classe de tipus, en comptes d'a un tipus fix, permetent-ne l'ús en posicions d'operands d'aquells tipus que les implementin.
| | literals i decodificació | literals i decodificació | literals i decodificació |
| literal (EBNF) | classe | funció decodificadora o de conversió | extensió de llenguatge |
| 9{9} -[\.E] (* dígits sense parts decimal/exp. *) | Num (anell) | fromInteger | |
| 9{9}[\.{9}] ['E'[±]9{9}] (* notació científica *) | Fractional (cos) | fromRational | |
| 9{9}[\.{9}] ['E'[±]9{9}] (* n.c. avaluable a enter *) | Num (anell) | fromInteger | NumDecimals |
| '"' caràcter {caràcter} '"' (* seqs. de caràcters*) | IsString | fromString | OverloadedStrings |
| '\[' valor {',' valor} '\]' (* seqs. de valors *) | IsList | fromList | OverloadedLists |

###### Sobrecàrrega de literals String

Així com els literals numèrics obtenen el tipus de la signatura de les operacions en que intervenen, la classe IsString fa possible això mateix per als literals String admetent-ne l'ús en posicions d'altres tipus que n'implementin la conversió, en el mètode fromString de la classe IsString. Cal especificar l'extensió de llenguatge OverloadedStrings.
| | implementa classes |
| tipus | IsString |
| [Char] | Sí |
| ByteString | Sí |
| Text | Sí |
A partir de GHC 7.8, els literals String, si hi ha l'extensió OverloadedStrings, ja no tenen tipus String, sinó que el tipus es descriu de manera existencial com un tipus d'aquells que implementen IsString
    (IsString t) => t
de manera similar als literals numèrics.

###### Sobrecàrrega de literals Llista

* Des de GHC 7.8. OverloadedLists: Els literals llista poden passar com a literals d'altres tipus que implementin (IsList t) aportant-hi la conversió.
| | implementa classes | implementa classes |
| tipus | IsList | Item (tipus de l'element del literal per a la instància) |
| [ε] | Sí | ε |
| NonEmpty ε | Sí | ε |
| Text | Sí | Char |
| Seq ε | Sí | ε |
| IntSet | Sí | Int |
| Set ε | Sí | ε |
| IntMap ε | Sí | (Int, ε) |
| Map κ ε | Sí | (κ, ε) |
| HashSet ε | Sí | ε |
| HashMap κ ε | Sí | (κ, ε) |
* Exemple de generació d'instàncies d'IsList per a HashSet i HashMap, però sobre tipus derivats amb newtype altrament donaria error per duplicació. Vegeu instàncies òrfenes.

## Preprocessadors
### Compilació condicional amb codi CPP

Inclusió de codi de preprocessador de C (CPP). Compilació condicional.
Cal esmentar el senyal de compilació -cpp o bé la pragma d'extensió de llenguatge {-# LANGUAGE CPP #-}.
El valor de la constant __GLASGOW_HASKELL__ definida pel compilador està relacionat amb els dos primers nombres de la versió de GHC que si és x.y.z llavors __GLASGOW_HASKELL__ == xyy, per ex. 708 per a GHC 7.8.*, 710 per a GHC 7.10.*.
El gestor de projectes Cabal genera amb cabal build el fitxer de macros dist/build/autogen/cabal_macros.h definint per cada biblioteca l'identificador de versió i una macro.
Això permet especificar compilació condicional segons la versió de biblioteca.
* Recomanat: Mòduls de compatibilitat per als casos de trencament de l'API

### altres preprocessadors

El gestor de projectes Cabal obté la llista de mòduls del fitxer de projecte (proj.cabal). Aquests mòduls poden correspondre a fitxers amb extensions diverses. Segons l'extensió, Cabal hi aplica el preprocessador corresponent, generant el fitxer de codi Haskell a compilar.
* cas de document de programa, extensions {.hs, .lhs}, ja tenim el codi font.
preprocessadors gramaticals :
| extensió d'origen | convertidor | notes |
| .x, .lx | alex | document d'analitzador de lèxic, de l'estil del programa en C lex |
| .y, .ly | happy | document d'analitzador gramatical, de l'estil del Yacc |

#### preprocessadors de generació de codi d'enllaç amb biblioteques d'altres llenguatges

Vegeu HaskellWiki - Foreign Function Interface
preprocessadors FFI :
| extensió d'origen | convertidor | genera | notes |
| .hsc | hsc2hs | .hs, mòdul_hsc.h, mòdul_hsc.c | haskell amb incrustacions de C |
| .gc | greencard | .hs, .h, .c | document haskell GreenCard |
| .h | c2hs | .hs | generador de haskell partint de signatures en C |

## Forats en expressions per consultar-ne el tipus (ang: Type Holes)

És una nova característica de GHC 7.8 que permet consultar el tipus que pertoca a una posició de paràmetre actual en una expressió, designada amb el guió baix '_', abans d'escriure-hi una expressió.

## Depuració

Pistes per la depuració aquí.

### El problema de la manca d'informació de situació en les petades

Quan una funció definida parcialment, crida la funció error, el programa peta oferint, escassament, el missatge de la funció error en versions anteriors a GHC 8.0. A partir de GHC 8.0 el missatge afegeix la posició de la funció error excepte per al paquet base.
Per exemple, en cas de manca en la consulta en un diccionari Data.Map (dicc ! clau), dona l'error "Map.find: element not in the map". Cap pista (a GHC) de la situació de la crida a error, ni de la rutina de procedència, ni del valor causant de l'error. (no s'exigeix que les claus dels Map siguin textualitzables (instàncies de Show)).
A Haskell no hi ha la pila per a crides dels llenguatges estrictes sinó que la pila és només d'expressions pendents d'ésser avaluades per a diferents patrons. Per tant, tampoc tindrem el bolcat de crides per situar-se.
* A partir de GHC 7.4.1, per quan es compila amb l'opció de l'ajustatge de rendiment (ang:profiling), (ghc -prof -fprof-auto), s'ha habilitat una reescriptura del codi intern per la simulació d'una pila de crides estricta, per obtenir-ne una traça de crides (sense posicions de les crides) en cas d'excepció. Cal afegir +RTS -xc al llançament del programa.
* A partir de GHC 7.8.1 hi ha una versió d'error errorWithStackTrace del mòdul GHC.Stack, que per bolcar la pila de crides (amb les posicions) requereix haver compilat i relligat amb les opcions d'ajustatge (ang:profiling)(ghc -prof -fprof-auto). Les opcions d'execució de depuració (+RTS -xc) no són necessàries.
   * GHC 8.0: errorWithStackTrace ha sigut devaluada (ang:deprecated). Ara error incorpora la funcionalitat de errorWithStackTrace. L'anterior error passa a denominar-se errorWithoutStackTrace. Les crides a error a la biblioteca base han estat reanomenades a errorWithoutStackTrace !!.
* A partir de GHC 7.10.2 hi ha la possibilitat d'explicitar les crides a traçar amb paràmetres implícits (definits a l'àmbit que fa la crida) específics (?loc :: CallStack), i NO requereix l'ús del RunTimeSystem d'ajustatge, com s'explica a #Obtenció programàtica del punt de crida. Cal l'extensió ImplícitParams.
* A partir de GHC 8.0 hi ha un truc per estalviar l'ús de l'extensió de sintaxi ImplicitPararms que és la definició de la restricció HasCallStack, fixant el nom de la variable de la pila de crides i fent que la crida a error la bolqui automàticament. (vegeu exemple)
   * Atenció: l'ús de CallStack/HasCallStack no funciona si no hi ha continuïtat en la propagació de l'àmbit de la variable implícita a les crides intermèdies, repetint la restricció a totes elles.
       Per exemple a GHC 8.2, Data.Map.(!) del paquet containers no esmenta HasCallStack a la crida, per tant l'ús de HasCallStack en una rutina d'usuari que la invoqui NO afegirà el punt de crida a la pila de crides del missatge d'error perquè la primera crida no s'apila a la pila de la rutina que té la crida a error.
* L'ús de l'ajustatge (ang:profiling) requereix relligar el programa amb la versió profiling del RunTimeSystem. Per fer proves amb perfilat cal disposar d'una compilació amb -prof de totes les biblioteques que relliguem.
    Per evitar l'error de manca de biblioteca de perfilat en les dependències, cal generar versions amb perfilat de les biblioteques que s'instal·lin. Per això, per al desenvolupament en aïllament (sandbox), convé afegir l'opció de perfilat per defecte (library-profiling: True) a l'arxiu de configuració de cabal específic del projecte (cabal.config) a la carpeta del projecte.
Tanmateix si sabeu per on poden anar els trets, es pot anar acorralant amb paranys (catch) i afegir traces als llocs sospitosos.

#### Traça de crides a l'intèrpret GHCi

Des de GHC 8.0.1 (excepte per a Windows): Vegeu ref.
Exemple de bolcat de pila de crides per excepció amb prova de crida errònia d'una clau inexistent al diccionari:
    CallStack (from HasCallStack):
       La restricció HasCallStack aquí no funciona (no afegeix els punts de crida de l'exemple en cas d'excepció) perquè l'àmbit de la variable implícita ?callStack no es propaga amb continuïtat entre la crida a error i la funció amb HasCallStack de l'exemple (hi ha funcions interposades sense la restricció HasCallStack que, per tant, no connecten la variable implícita amb l'àmbit del punt de crida, per exemple Data.IntMap.(!)).
    CallStack (from -prof):
       La compilació d'ajustatge (ang:profiling), en cas d'excepció mostra els punts de crida corresponents als mòduls compilats amb l'opció -prof.

#### aproximació amb paranys (catch)

Desavantatge: Les clàusules catch no es poden utilitzar dins el codi funcional, sinó només en codi de la mònada IO. El paquet exceptions aporta una implementació vàlida en altres mònades.
El catch del Prelude està devaluat (eliminat a GHC v. 7.6.1) en front del recomanat de Control.Exception.
La funció catches evita la situació produïda en una seqüència d'aplicacions de catch (per gestionar diferents tipus d'excepcions), on una excepció produïda dins un handler pot ser interceptada pel catch següent.
Vegeu també #Punts de control al codi amb Loch-TH.

#### aproximació amb traces

Desavantatges:
* en el codi funcional l'ordre d'impressió de múltiples traces és aleatori perquè l'ordre d'execució de subexpressions és indeterminat.
* en el codi monàdic (seqüencial) a causa de l'avaluació tardana, s'imprimeix quan s'avalua i no pas en l'ordre especificat.

#### aproximació amb depuració a l'intèrpret ghci

Amb GHCi debugger, Vegeu l'article "No more exceptions: debugging Haskell code with GHCi". establint punts d'aturada (break-points)
* cal habilitar el senyal break-on-exception
* l'excepció ErrorCall, generada per la crida a la funció error, provoca l'aturada
* amb :back retrocedeix al punt d'aturada (ang:break-point) anterior
      * GHCi permet magatzemar en un fitxer "./.ghci" les ordres a executar en arrencar ghci, facilitant desar una llista de ordres de càrrega de mòduls i declaració de break-points per a un ús reiteratiu. Requereix permís d'escriptura exclusiu del propietari al fitxer i al directori.
       (a UNIX caldrà desactivar el permís d'escriptura de grup del fitxer i del directori: chmod g-w ".ghci" && chmod g-w $PWD)

#### Obtenció programàtica del punt de crida

Des de la versió 7.10.2 existeix un mecanisme per l'obtenció programàtica del punt de crida, per a ser inclòs en missatges d'error, com es descriu a l'exemple.
A l'hora d'obtenir-ne el valor, es mostren només les crides corresponents al nom de variable implícita coincident.
Per a versions anteriors la biblioteca file-location permet incloure la posició actual en missatges d'error. Vegeu exemple a la secció següent.

### Traslladant la petada de les funcions parcials a la rutina que la crida amb paràmetres no vàlids

La crida a la funció error genera una excepció genèrica ErrorCall que cal evitar perquè proporciona molt poca info. de l'error.
Una solució: substituir la funció parcial per una de resultat opcional (Maybe) i avaluar-ne el resultat.
* Si n'avaluem només el patró esperat, i es dona l'inesperat, la petada de l'encaix dona informació de la situació.
* Però és més correcte avaluar tots els patrons i assenyalar l'error amb la funció (err') del paquet file-location que, mitjançant una crida splice ($(x)) (extensió TemplateHaskell), avalua, en temps de compilació, la posició de la crida.
Resultat:

#### La biblioteca Safe millora les funcions parcials del Prelude

La biblioteca Safe ofereix diverses versions de les rutines predefinides al Prelude que poden petar.
* sufix Def per a versions amb valor per defecte per al cas no definit.
* sufix May per a versions amb resultat opcional (Maybe)
* sufix Note per a versions amb afegitó per etiquetar el missatge d'error per distingir-ne l'origen,
* sufix Safe: cas de no definició, retorna l'element zero del mateix tipus. (tailSafe =; initSafe =)
Exemple: at: funció substitutiva de la indexació de llistes (!!), definida parcialment per a valors no negatius de l'índex, menors que la llargada:

### Evitant les funcions parcials

El més convenient és evitar les funcions parcialment definides substituint-les per totals,
* amb resultat opcional, analitzant el resultat per patrons
* proporcionant un valor per defecte per al cas no definit
* definint un tipus específic per al subdomini vàlid, amb generadors que en validin els valors.

#### Opcions de compilació per evitar fallades

Vegeu ref.
* -fwarn-incomplete-patterns : avisa quan l'encaix pot fallar
* -fwarn-incomplete-uni-patterns : avisa quan l'encaix en una lambda és incomplet
* -fwarn-incomplete-record-updates: avisa quan les actualitzacions de registres poden fallar

#### Un Prelude alternatiu sense funcions parcials

El paquet classy-prelude ofereix diversos avantatges, i es pot utilitzar amagant el Prelude oficial amb la pragma {-# LANGUAGE NoImplicitPrelude #-}
Incorpora, a més a més, la biblio. mono-traversable que proposa un tractament unificat de col·leccions, tant monomòrfiques com paramètriques, basat en famílies de tipus.

### Evitant les petades amb Verificació Formal estàtica

Afegint anotacions de "tipus refinats amb predicats".
Vegeu #Verificació Formal estàtica amb la biblio LiquidHaskell

### Punts de control al codi amb Loch-TH

El paquet loch-th aporta una solució a les assercions fallides, generant automàticament en els punts de control $check <expr>, amb template haskell, gestors d'excepcions sobre l'expressió que prefixen la situació (fitxer : línia : columnes) del $check al missatge d'error. (el prefix '$' avalua en temps de compilació la funció o expressió (entre parèntesis) prefixades)
la seva execució, en cas d'excepció, mostra les posicions dels $check travessats:

#### Loch-TH i els constructors

$check avalua amb evaluate que ho fa a WHNF per tant les expressions dels components dels contructors no són avaluades. Caldrà explicitar l'avaluació estricta per forçar-ne l'avaluació per aflorar les excepcions. Vegeu explicació a Haskell / estrictesa
force del paquet "deepseq" avalua estrictament també els components (avaluació a Forma Normal), si el tipus implementa la classe NFData del mateix paquet. El paquet deepseq-th aporta la derivació genèrica d'instàncies NFData per a tipus de dades algebraics.
dona, mostrant si s'avalua o no el codi erroni, assenyalant-ne la posició:

### Traçabilitat

Vegeu ref.

#### En el codi funcional

L'ordre d'impressió de diverses traces en una expressió serà aleatori!!, perquè l'ordre d'execució de subexpressions en el codi funcional és indeterminat.
* trace: mostra un missatge mitjançant unsafePerformIO
* traceShow: mostra el valor d'una variable textualitzable
* traceStack (des de GHC 7.4): Cal compilar amb la biblio. de perfilat (ang:profiling) com trace afegint la pila de crides simulada de l'estudi de costos.

#### En context seqüencial

* traceIO: mostra el missatge en el context de la mònada IO, retornant unit.
* traceM: mostra el missatge en un context seqüencial (monàdic o bé aplicatiu), retornant unit.
* traceShowM: mostra el valor d'una variable textualitzable en context seqüencial (monàdic o bé aplicatiu), retornant unit.

#### EventLog Tracing

És una traça per al registre d'esdeveniments, per a ser llegides per eines per l'ajustatge del rendiment (perfilat, ang:profiling).
* Cal compilar amb l'opció -eventLog.
* per a mostrar la traça textualment, cal compilar a més a més amb -debug i executar amb +RTS -v[flags]. Mostra les traces pel dispositiu de sortida stdout.
* per a un ús de la traça per eines de perfilat, s'envien les traces al fitxer nom_programa.eventlog, amb codificació binària (més compacte), executant amb +RTS -l[flags].
Exemple:

## Més problemàtiques
### El problema de les configuracions

Se n'hauria de dir millor "el problema de les preferències canviants" o "de l'entorn global modificable".
L'accés, des del codi funcional, a variables globals carregades en temps d'execució es pot abordar des de diverses perspectives, cap d'elles plenament satisfactòria.
* Amb la mònada Reader (proporciona accés a variables d'entorn d'un entorn canviant). Desavantage: no-accessible des del codi funcional, caldrà, llavors, passar-lo com a paràmetre.
** Intent de solució mitjançant paràmetres implícits: Desavantatge: cal propagar el paràmetre implícit a totes les declaracions de tipus de les rutines intermèdies.
* Accedint via unsafePerformIO, assegurant-se bé que l'escriptura de les variables ha estat avaluada ("the unsafePerformIO hack"). Desavantatge: hi ha el risc que les ops. no s'efectuïn en l'ordre correcte si no se'n controla bé l'avaluació.
* Altres sistemes més sofisticats:
** Segons Joachim-Breitner
** Segons Oleg Kiseliov i Chung-chieh Shan

#### Una solució: El hack unsafePerformIO

unsafePerformIO És una manera poc ortodoxa de definir variables globals mudables, com les ref del ML, modificar-les i accedir-hi des de codi funcional pur, sense necessitat de passar-les com a paràmetre
La variabilitat de les definicions globals trenca el principi de transparència referencial (constància del resultat d'una funció amb les mateixes entrades) de les funcions que hi accedeixen.
El resultat dependrà de l'ordre de les operacions mutadores i del moment que se n'avaluï el thunk corresponent. (Vegeu "IO inside: The dark side of the IO Monad".)
hack, en informàtica, segons la viqui. anglesa vol dir "solució poc elegant però que permet sortir del pas", aquí en diríem "un pedaç".
unsafePerformIO és la porta del darrere de la mònada IO.
Per emprar amb seguretat unsafePerformIO en el codi funcional, cal que l'acció no-funcional mantingui la idempotència (no tingui efectes col·laterals i sigui independent de l'entorn).
Aquesta solució és incompatible amb la certificació Safe Haskell.
El sistema més correcte és tractar les preferències com un entorn canviant, fent servir la mònada Reader o bé el transformador de mònades corresponent ReaderT com s'explica tot seguit.

#### Tractament d'un entorn canviant, amb la mònada Reader

És la millor solució al problema de les preferències (variables globals) que tracta com un entorn variable mitjançant l'aplicació d'una funció (entorn -> entorn)
Exemple d'ús del transformador de mònades equivalent de la mònada Reader (ReaderT) en un procés interactiu:

### El problema del sobreiximent de la pila

L'ús del "plegat per l'esquerra estricte" foldl' no garanteix que es treballi a espai constant de la pila.
En cas de funcions amb recursivitat final,
* les expressions (o variables definides localment) en la crida recursiva generen thunks pendents d'avaluar, que s'apilen mentre no s'arriba al cas no recursiu.
* l'avaluació estricta (amb '!' BangPatterns (a WHNF)) en els paràmetres acumuladors tampoc ho garanteix, si l'avaluació es topa amb un constructor perquè per disseny els constructors aturen l'avaluació.
Vegeu "Stack overflow" al HaskellWiki i la secció Haskell#Avaluació estricta explícita (treballar a espai constant de la pila). També "Retainer profiling" per investigar "Perquè l'avaluació d'un objecte és retinguda"
La solució més fàcil és que el tipus de l'acumulador algebraic estigui definit estricte (prefix '!') en tots els seus components.
Altrament el paquet deepseq aporta funcions d'avaluació en profunditat a Forma Normal. El paquet deepseq-th facilita la derivació d'instàncies de la classe NFData (contracció de NormalFormData), només per als tipus algebraics. Altrament caldrà instanciar-la manualment, definint la funció rnf (acrònim de reduce to normal form) de manera que per cada constructor n'avaluï tots els components.

### El problema de les fugues de memòria

Vegeu enllaços "Memory leaks"," Space leak zoo"
Eines per l'ajustatge: "GHC: Perfilant (ajustant) l'ús de memòria".

### El maleït problema de les dependències de biblioteques (ang: cabal dependency hell)

El relligat requereix que hi hagi una sola versió de cadascuna de les biblioteques relligades.
El desenvolupament en aïllament (sandbox) es fa per evitar dependre de biblioteques instal·lades en l'entorn d'usuari, subjectes a alteracions per la instal·lació d'aplicacions i també per evitar que estiguin relligades amb biblioteques instal·lades relligades al seu torn amb versions diferents d'una mateixa biblioteca.
cabal sandbox init inicialitza un dipòsit de biblioteques exclusiu del projecte, que impedeix tenir múltiples versions instal·lades d'una mateixa biblio.
Tanmateix la incorporació a posteriori de biblioteques en un projecte, pot portar a la situació que les dependències de la nova siguin incompatibles amb el conjunt de biblioteques instal·lades, i calgui eliminar el dipòsit i reintentar-ho de cap i de nou, havent de reinstal·lar-ho tot, amb la consegüent aturada d'hores que suposa la recompilació d'un programa complex per la quantitat de biblioteques com ara els servidors web yesod.

#### Stackage - rebost alternatiu amb dependències verificades

Stackage vol ser una solució al problema de les dependències (biblioteques de les quals es depèn), oferint les biblioteques en conjunts de versions compatibles entre elles per una determinada versió de GHC garantint la correctesa de la compilació. L'evolució per modificació de les biblioteques resultarà en un seguit d'imatges instantànies (ang: snapshots) del conjunt de biblioteques, promovent que tots els autors s'actualitzin quan es produeix una modificació en una biblio. que trenqui la compatibilitat, quedant fora del conjunt les que no s'actualitzin.
Les imatges etiquetades "Nightly" (compilació nocturna o en desenvolupament) tenen versions més recents de biblioteques, però poden ometre aquelles endarrerides respecte al suport de dependències que han modificat l'API i les que en depenguin, mentre que les etiquetades LTS Haskell (Long Term Support) són més completes però no tant recents.
Cal especificar el rebost al fitxer cabal.config de la carpeta del projecte amb la propietat remote-repo. I després fer cabal update des del mateix directori.
Exemple per a l'edició lts-6.27:
Stackage, contracció de "Stable, Vetted Hackage" (cat: rebost Hackage estable i verificat), és una iniciativa dels creadors de l'entorn de desenvolupament web Yesod, auspiciada per FPComplete.
* També s'ofereix una eina stack, que treballa amb el rebost Stackage i millora el desenvolupament en aïllament de cabal sandbox. Vegeu Haskell#Stack - Meta-gestor de projectes

## Programació de nivell baix
### Aspectes d'optimització

* "Més aviat: com fer que un programa compili més de pressa".
* "Més ràpid: com fer que un programa corri més".
* "Més petit: com fer que un programa ocupi menys".
* "Més auster: com fer que un programa engoleixi menys memòria dinàmica".

### Optimitzacions d'allotjament
#### Tipus primitius que es passen per valor (no encapsulats, ang:unboxed)

Boxing és el procés de convertir una dada que es passa per valor en un objecte que es passa per referència. Unboxing és el procés invers.
Els valors "no encapsulats" eviten l'allotjament en memòria dinàmica, però en ésser valors nus no disposen d'informació de tipus i les funcions polimòrfiques no s'hi podrán aplicar.
Els operadors, tipus i literals de dades "unboxed" hauran de dur un indicador '#' al darrere, extensió de sintaxi que requereix la pragma {-# LANGUAGE MagicHash #-}:
* tipus: Int#, Float#, Double#
* operadors: (+#), (-#), (*#), (==#)
* literals: 4# 3.2# 'c'#

##### De unboxed a boxed

* el tipus de 4# és Int# ;
* Amb el constructor I# de GHC.Exts, el tipus de (I# 4#) és Int

##### De boxed a unboxed per encaix

Vegeu i el farragós exemple següent:

#### Desencapsulament en un tipus - La pragma UNPACK

Desempaqueta un component d'un constructor de dades en el mateix constructor evitant un nivell d'indirecció.
La pragma {-# OPTIONS_GHC -funbox-strict-fields #-} ho fa automàtic.
Des de ghc 7.8, la optimització UNPACK ve per defecte, per als components estrictes de mida "petita" (igual o inferior a la de la paraula de la màquina, i també per als de coma flotant).

#### Tuples no encapsulades per al retorn de múltiples valors

Les tuples unboxed
són un capítol a part i s'utilitzen per retornar més d'un valor alhora, sense allotjar la tupla a la memòria dinàmica. Cal especificar l'extensió de lleng. UnboxedTuples i l'opció -fobject-code (generació de codi nadiu, perquè en codi intermedi (bytecode) no compila).
Compilació i exec.
./tuples-no-encapsulades

### Especialització d'operacions sobrecarregades

L'especialització es fa servir per millorar el rendiment en les operacions sobrecarregades, quan es fan servir molt amb un tipus concret. Cal especificar la pragma SPECIALIZE.
-- en detectar el compilador el tipus esmentat a la pragma, genera versions no sobrecarregades, més eficients, de la funció.

## Safe Haskell

Vegeu ref. És una extensió de llenguatge per restringir l'ús de diverses construccions, com ara unsafePerformIO que permet trencar la transparència referencial de les expressions funcionals pures (constància del resultat en diferents invocacions amb les mateixes entrades).
Pretén assegurar les propietats següents:
* seguretat dels tipus
* transparència referencial
* encapsulament estricte de mòduls
* raonament modular
* consistència semàntica.
Cal esmentar la pragma {-# LANGUAGE Safe #-}.

## GHC a la màquina virtual Java

* eta-lang.org és una modificació de GHC per generar codi JVM dels executables i biblioteques en fitxers ".jar" amb interoperabilitat amb classes Java, permetent l'ús de biblioteques haskell actuals en entorn Java, amb suport per la majoria d'extensions de GHC.
   * eta: és el nom que pren el GHC modificat, admetent sintaxi FFI (Foreign Function Interface) ampliada d'enllaç amb Java per a l'importació / exportació, (<:) per al requeriment d'implementació d'interfícies Java, ...
   * etlas: és una adaptació del programa cabal.
* Frege és una aproximació a Haskell sobre la JVM incompatible amb l'estàndard del llenguatge. (ex. a les def. de classes el nom de la classe precedeix el requeriment de context, al revés del Haskell, la precedència dels operadors atorga nivells de 0 a 16 quan al Haskell és de 0 a 9, ...)

## JavaScript com a rerefons de GHC (Haskell al navegador web)

JavaScript té el desavantatge de tenir un codi molt fràgil, però és una eina que s'hi pot comptar a tots els navegadors web.
Haste desenvolupat a la Universitat Chalmers de Göteborg i també GhcJs són modificacions de GHC amb generació de codi JavaScript partint de la sortida STG del compilador.
Permeten utilitzar primitives específiques juntament amb pràcticament qualsevol codi Haskell compilable amb GHC, i generar-ne codi JavaScript.
Exemple amb Haste, instal·lació (cal versió cabal-1.18+ per la compilació aïllada):
Programa d'exemple que mostra en un element html amb id="id_sortida", el contingut de la casella de text (elem. input type="text") amb id="id_entrada_de_text"
* Vegeu també PureScript

## Eines
### hlint

    Aquí analitzador de codi amb suggeriments de millora. Avisa de construccions redundants i proposa alternatives al codi.

### cabalg

    descarrega i instal·la des del GitHub. Obsolet (actualment les instal·lacions són via Stack)

### cabal-dev

    (ang:"Sandboxed haskell build environments") Permet desenvolupar un projecte cabal amb un dipòsit de biblioteques específic del projecte (sub-carpeta cabal-dev/), per aïllar-se d'interaccions amb les biblioteques de l'entorn d'usuari/sistema corresponents a les aplicacions instal·lades. Caldrà afegir a la var. d'entorn PATH la carpeta cabal-dev/bin.
      * Obsolet. La funcionalitat de cabal-dev ha estat incorporada al programa Cabal amb el verb sandbox i cabal-dev ja no s'actualitzarà. cabal sandbox init inicialitza el dipòsit de biblioteques del projecte en el subdirectori .cabal-sandbox deixant els executables a .cabal-sandbox/bin.

### cabal-meta (cabal multi-projecte)

    Permet especificar una llista de subprojectes locals o bé remots (git/hackage) per a un muntatge encadenat dels projectes dependents, en cas de modif. en un subprojecte. Obté la llista de subprojectes d'un fitxer sources.txt que pot referenciar altres directoris que també en continguin, per un tractament recursiu.
    .- instal·la (amb cabal-dev cas de --dev), en una sola ordre diversos paquets (del hackage o bé subprojectes de directoris locals o remots (git))
    .- als fitxers sources.txt cada línia pot contenir:
* cas de començar per '.' o bé '/': directori (seguit d'opcions) que pot contenir un altre fitxer sources.txt i/o un projecte cabal. (les opcions són flags per al cabal)
* cas de prefix "git:", "https", "http": gitLocation gitBranca? opció*, és a dir, projecte recuperable amb git (sistema de control de versions distribuït)(les opcions són flags per al cabal)
* altrament: paquet-del-hackage opció*

### cabal-ghci

    engega ghci preparant-lo per a proves del projecte, amb camins i extensions de llenguatge obtinguts del fitxer de projecte.cabal
* Obsolet !, Aquesta funcionalitat ha estat incorporada a cabal amb el verb repl (acrònim de read-eval-print loop) (cabal repl)

### yackage

    servidor de rebost "hackage" local per a desenvolupament.

### ThreadScope

    Visualitzador gràfic de les traces d'esdeveniments corresponents a cada "capacitat" (fil d'exec. corresp a un processador elemental, sobre el qual s'executen els fils d'exec. lleugers). Estudi "Ajustatge fi del paral·lelisme amb ThreadScope".

### hpc (haskell program coverage)

    Anàlisi de cobertura del codi. Mostra, després de diverses execucions, amb marcatge de colors quines parts del codi no s'han executat mai i condicions sempre certes o sempre falses.
* compilar amb l'opció -fhpc
* executar diverses vegades amb diferents entrades
* invocar: hpc markup nom_executable (genera hpc_index.html i altres html)
* obrir hpc_index.html amb un navegador
* per recomençar l'estudi, i també després de recompilar, cal eliminar el fitxer nom_executable.tix on guarda les traces d'execució.

### hp2any (obtenció del perfil d'ús de memòria)

* hp2any-graph mostra en temps-real un gràfic de l'evolució de l'ocup. de memòria.
* hp2any-manager mostra gràfics de fitxers de perfil (.hp) corresp. a execucions ja finalitzades.

### més eines de desenvolupament al HaskellWiki

Vegeu ref.

## Verificació Formal estàtica amb la biblio LiquidHaskell

"LiQuiD Types" és un nom adaptat de la contracció de "Logically Qualified Data Types".
La biblioteca LiquidHaskell permet la verificació mitjançant anotacions de "tipus refinats amb predicats" (actualment només de tipus enters) que cal acotar entre {-@ @-} com ara:
i aporta un programa de verificació formal, anomenat liquid, que utilitza un solucionador de lògica de predicats SMT (Satisfiability Modulo Theory) per comprovar que el codi compleix els predicats. A més incorpora comprovació de totalitat (contrari de parcialitat en funcions per garantir l'acabament dels programes).
Vegeu sintaxi, i l'apartat sobre mètrica dels tipus de dades: "2.6 Measures: From Integers to Data Types". Explicació més planera aquí. Vegeu bloc.
És convenient separar cada instrucció LH en un bloc {-@ @-} a part, per entendre millor els errors de l'analitzador sintàctic del liquid.
Líquid permet l'ús en predicats de mètriques dels tipus de dades. Per fer servir una funció com a mètrica cal especificar-ho al LH amb el qualificador measure.
Darrerament també és possible especificar mètriques d'acotació de funcions recursives per garantir-ne l'acabament.
Comprovació amb el solucionador de lògica de predicats SMT MathSAT:.

## Exemples

Degut a un robot viquipèdic que converteix les fletxes del codi -> en →, per poder compilar els exemples cal afegir l'extensió de llenguatge UnicodeSyntax, com ara {-# LANGUAGE UnicodeSyntax #-}.

### Arrencada amb opcions

Exemple amb definició i anàlisi d'opcions d'arrencada per al nostre programa.
Per afegir opcions a l'intèrpret d'ordres vegeu l'enllaç.

### Excepcions de tipus definits per l'usuari

Haskell2010 millora les excepcions del Haskell98, permetent definir-ne tipus nous (amb els camps que convingui), que només han d'instanciar Show i la implementació per defecte de la classe Exception, prèvia derivació de Data.Typeable
L'extensió DeriveDataTypeable facilita la derivació d'instàncies de Typeable pel compilador quan s'esmenta en una clàusula deriving.
Exemple:

### llistes per comprensió a l'estil de SQL

Incorporant transformacions a les llistes per comprensió amb la clàusula then. En cas d'emular una consulta SQL agrupada (Group by) cal prefixar els camps agrupats amb la clàusula the. Cal esmentar la pragma {-# LANGUAGE TransformListComp #-}
dona

### vectors a la mònada ST

La mònada ST permet elaborar funcions per a ser cridades des de codi funcional, que encapsulen l'encadenament de canvis d'estat d'àmbit local, en aquest cas, de vectors.
1.- Amb vectors amb índexs de tipus divers en un rang, i elements d'allotjament directe (Unboxed), com a (UArray tipusIndex tipusElem).
Creació del vector com a immutable, descongela a mudable (thaw), modificació, recongelació(freeze) i llistat:
2.- Amb vectors "eficients" (índex Int basat en 0) i tipus del vector (Vector tipusElem) del paquet Vector. Avantatge: implementa força més classes i disposa d'algoritmes específics al paquet vector-algorithms.

### diccionaris eficients amb HashMap

Hashable aporta instàncies de funció resum per als tipus més freqüents.
HashMap i HashSet són més ràpids que les implementacions basades en arbres, especialment quan la comparació de claus és lenta, com és el cas del tipus String.
L'anterior implementació de la biblioteca HashMap del paquet hashmap que feia servir un arbre balancejat per als cistells de claus coincidents requerint (Ord clau), ha quedat desaconsellada en favor de la biblioteca unordered-containers que fa servir llistes per als cistells requerint (Eq clau).

### Expressions regulars

Tots els paquets d'expressions regulars implementen (=~) que dona èxit i coincidències segons el tipus del resultat. (=~~) equival a (=~) en el context d'una mònada (text =~~ regex = return $ text =~ regex). Vegeu ref.
* L'operació (=~) està sobrecarregada, oferint diferents informacions segons el tipus del resultat, exigible amb una restricció de tipus:
   * Bool: indica si l'encaix té èxit
   * String: ofereix el text encaixat
   * MatchArray: informa de les posicions d'encaix dels grups, els elements són :: (posició, llargada)
   * (txt, MatchText txt, txt): informa (text_precedent, encaixos, text_posterior), l'elem. dels encaixos és :: (txt, (posició, llargada))
   * [MatchArray]: cerca múltiple oferint la llista [Array Int (posició, llargada)]
   * [MatchText txt]: cerca múltiple oferint la llista [Array Int (txt, (posició, llargada))]
En cas d'efecte lateral per l'ús d'una biblioteca externa, l'operador (=~~) ofereix la mateixa funcionalitat que (=~) però en el context seqüencial d'una mònada.
Prova: cabal install regex-pcre

### serialització en format JSON

Per als tipus que instancien la classe Generic (tipus algebraics i d'altres) se'n poden derivar les classes {ToJSON, FromJSON} automàticament.
Amb l'ús de l'extensió DeriveAnyClass, per als tipus algebraics és tan fàcil com afegir les classes {Generic, ToJSON, FromJSON} a la clàusula deriving. Requereix el paquet aeson.
dona:

### arbres

Vegeu ref.
dona el resultat:

### Combinació de filtres

La classe Applicative permet combinar, amb una funció o bé un constructor, els resultats d'una seqüència de computacions.
Prenem com a tipus que l'implementa, les funcions amb entrada del mateix tipus
Exemple de combinació.

### QuickSort amb Data Parallel Haskell

Vegeu #Data Parallel Haskell i ref.
1. Mòdul d'operacions vectoritzades
2. Mòdul d'operacions NO-vectoritzades
* Compila i executa

### Interfícies gràfiques
#### Hola món amb GTK

Web del projecte GTK per a Haskell aquí.
Cal que el sistema tingui instal·lades versions de desenvolupament (acabades en -dev) de les biblioteques gràfiques
Si apareix el missatge "Undefined symbol ___gxx_personality_v0 on link" cal afegir la biblioteca stdc++ al relligat.

#### Hola món amb WxHaskell

WxHaskell és una implementació de l'entorn gràfic Wx que és multi-plataforma.
Cal haver instal·lat prèviament les biblioteques wx de desenvolupament per al sistema subjacent.

### Lents de Van Laarhoven -- Consulta i manipulació de parts d'estructures complexes

Una lent (referència funcional) és un mecanisme componible que permet enfocar un component d'una estructura per ésser manipulat en tant que integrant de la mateixa. Vegeu refs. Exemple amb el paquet lens de Eduard Kmett.
Vegeu també Haskell#Lents basades en profunctors
Nota de l'exemple: la funció properFraction correspon a la definició de Fracció pròpia.

### Extreure informació d'un document XML

Vegeu-ho a Fletxa (programació funcional)#Exemple - Extreure informació d'un document XML

### Operacions als tipus - Tipus dependents de valors

Vegeu ref.
Fins ara hi ha hagut algunes iniciatives partint dels nombres de Peano obtenint sèries curtes de tipus mono-valor anomenats en anglès singleton types (cat: tipus solters, volent dir monovalor) o algunes definicions inductives més sofisticades.
* Remarcable: El paquet dimensional-tf incorpora als tipus les dimensions de les unitats de la física.
passa la comprovació de tipus i dona:

### Naturals als tipus

La proposta TypeNats ("Type level natural numbers"), parcialment implementada a GHC 7.6.1, permet l'ús de naturals als tipus facilitant les proposicions inductives als tipus.
Cal fer servir l'endollable (ang:plugin) de GHC type-nat-solver de Iavor Diatchki (opció de compilació -fplugin=TypeNatSolver inclosa al codi, i afegir el paquet type-nat-solver a les dependències de l'aplicació.
Ampliant l'exemple. Compilat amb GHC 7.10.1.
Mòdul de nombres de Peano de tipus singulars (d'un sol valor) (ang: singleton types).
Mòdul de contenidor amb naturals al tipus.

## Precisió dels tipus bàsics

En un processador x86-64 amb GHC:
Els sencers ofereixen, a GHC, el rang complet corresp. a la paraula de la màquina (malgrat que l'especificació de Haskell només exigeix un mínim [-2^$^{29}$.. 2^$^{29-1}$]), i no fan com altres compiladors (OCaml#tipus bàsics, SML#Precisió dels tipus bàsics) que sacrifiquen un bit per optimitzar el tractament intern conjunt de sencers i de punters.
En coma flotant, sembla que els valors dels exponents oferts per floatRange donen un valor esbiaixat respecte a la intuïció. L'intèrpret GHCI dona correctament
Però el truc és que l'exponent no correspon a la notació científica, sinó al component de la representació interna IEEE 754 segons l'especificació per a coma flotant del "Language Independent Arithmetic standard".
* La notació estandarditzada per a coma flotant de 1 és (en base 2): 0.1$_{base2}$ * 2^1
A ghci:
Relacionat: Hi ha tres operadors d'exponenciació (^), (^^), (**) segons que el domini de l'exponent sigui natural, sencer, o real en coma flotant.

## Compilació de mòduls amb referències mútues (cicles)

* Vegeu
Encara que sovint és possible evitar aquesta situació quan es dissenya l'aplicació, si es tracta d'una modif. i el disseny no convé alterar-lo, caldrà trencar les importacions circulars, seguint les instruccions, creant un subconjunt del mòdul com a Mòdul.hs-boot, i referir-s'hi des dels altres mòduls afegint la pragma SOURCE a la clàusula import.
No caldrà fer-ne esment en el fitxer de projecte.cabal. El gestor de projectes cabal, busca totes les extensions de fitxer per cada nom de mòdul, trobarà l'extensió ".hs-boot" i hi aplicarà el preprocés adequat.

## Referències

* ↑ mmc - Compilador Mercury de Melbourne(anglès)
* ↑ web del Compilador Haskell de York Arxivat 2013-12-15 a Wayback Machine.(anglès)
* ↑ web del Compilador Haskell d'Utrecht Arxivat 2014-07-22 a Wayback Machine.(anglès)
* ↑ web del C--(anglès)
* ↑ Diagrama de blocs del ghc que incorpora C--(anglès)
* ↑ El llenguatge Cmm(anglès)
* ↑ Estàndard actual del llenguatge Haskell
* ↑ La "Plataforma Haskell"(anglès)
* 1 2 3 API de la Platforma Haskell Arxivat 2016-12-20 a Wayback Machine. Seleccioneu-ne la versió(anglès)
* ↑ Anunci de la GHC 6.12.1(anglès)
* ↑ How to play with Stack
* ↑ How to script with Stack
* ↑ How to build with Stack
* ↑ Biblioteques i mòduls estàndard actuals
* ↑ Versions de biblioteques de les edicions de GHC(anglès)
* ↑ Libraries Version-history(anglès)
* ↑ Proposal: Remove Control.OldException(anglès)
* ↑ Biblioteques del GHC 7.4.2(anglès) Control.OldException encara hi és Les excepcions del H98 estan suportades
* ↑ Biblioteques del GHC 7.6.1(anglès) Control.OldException ja no hi és Les excepcions del Haskell98 ja no estan suportades
* ↑ The Glasgow Haskell Compiler(anglès)
* ↑ Documentació del compilador GHC
* ↑ Opcions del RunTimeSystem per controlar la mem. dinàmica i el recollidor de memòria brossa Arxivat 2010-04-02 a Wayback Machine.(anglès)
* ↑ RTS - Envelliment(anglès)
* ↑ RTS - Allotjament en Blocs
* ↑ RTS - El planificador(anglès)
* ↑ El recollidor de brossa(anglès)
* ↑ RTS - El recollidor de brossa.
* ↑ mòdul System.Mem(anglès)
* ↑ Simon Peyton Jones, et. al. - Stretching the storage manager(anglès)
* ↑ mòdul System.Mem.Weak(anglès)
* ↑ Control.Concurrent.MVar.mkWeakMVar(anglès)
* ↑ Ús de biblioteques d'enllaç dinàmic (anglès)
* ↑ Suport d'enllaç dinàmic a les diferents plataformes (anglès)
* ↑ Building and using Win32 DLLs(anglès)
* ↑ Parallel Haskell Digest(anglès)
* ↑ El paquet meta-par(anglès)
* 1 2 HaskellWiki - A Repa Tutorial(anglès)
* ↑ REgular PArallel arrays(anglès)
* ↑ Haskell - Paral·lelisme de dades
* 1 2 Nested Data Parallelism - presentació (diapos)
* ↑ Paquet dph-examples
* ↑ Guy E. Blelloch - Programming Parallel Algorithms - Nested Data Parallellism
* ↑ GHC.Prim - SIMD Vectors(anglès)
* ↑ SIMD instructions in GHC (anglès)
* ↑ Paquet simd
* ↑ Paquet primitive-simd
* 1 2 UNSW.edu.au - An Embedded Language for Accelerated Array Computations(anglès)
* ↑ Biblioteca Accelerate per al paral·lelisme a les GPU(anglès)
* ↑ biblioteca accelerate-cuda(anglès)
* ↑ El paquet accelerate-opencl(anglès)
* ↑ El paquet accelerate-repa(anglès)
* ↑ paquet OpenCLWrappers(anglès)
* ↑ OpenCL from Haskell Arxivat 2012-01-21 a Wayback Machine.(anglès)
* ↑ How to write hybrid CPU/GPU programs with Haskell(anglès)
* ↑ Hackage - paquet accelerate(anglès)
* ↑ Hackage - paquet accelerate-cuda(anglès)
* ↑ CUDA developer zone(anglès)
* ↑ accelerate-opencl de HIPERFIT(anglès)
* ↑ NVIDIA OpenCL(anglès)
* ↑ AMD APP SDK – A Complete Development Platform Arxivat 2016-02-09 a Wayback Machine.(anglès)
* ↑ accelerate amb rerefons OpenCL-Cilk(anglès) Subcarpeta icc-opencl
* ↑ accelerate-repa(anglès)
* ↑ accelerate-llvm(anglès)
* ↑ Template Haskell(anglès)
* ↑ Haskellwiki - QuasiQuotation(anglès)
* 1 2 Yesod - plantilles(anglès)
* ↑ Sintaxi dels quasiQuoters Arxivat 2013-04-14 at Archive.is(anglès)
* ↑ «QuasiQuotation». Arxivat de l'original el 2013-04-14. [Consulta: 5 octubre 2011].
* ↑ Tipus algebraics del TemplateHaskell (anglès)
* ↑ Haskellwiki - Quasi-Quotation(anglès)
* ↑ Constructor QuasiQuoter al paquet template-haskell(anglès)
* ↑ Template Haskell - stringE(anglès)
* ↑ Fusionant successius Map: Fent que Haskell sigui un 225% més ràpid (anglès)
* ↑ From lists to streams to nothing at all(anglès)
* ↑ Loop fusion (anglès)
* ↑ Stream fusion for Haskell Arrays (anglès)
* 1 2 paquet Stream-fusion(anglès)
* ↑ API del GHC(anglès)
* ↑ API Contenidors(anglès)
* 1 2 3 4 5 6 7 8 9 10 11 12 13 Data.Set
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Data.Map
* 1 2 3 4 5 6 7 8 9 10 11 12 Data.IntSet
* 1 2 3 4 5 6 7 8 9 10 11 12 Data.IntMap
* ↑ paquet hashmap (anglès)
* ↑ Data.HashSet del paquet hashmap(anglès)
* ↑ Data.HashMap del paquet hashmap(anglès)
* 1 2 paquet Hashable(anglès)
* ↑ El paquet unordered-containers (HashMap i HashSet que no requereixen claus ordenables)
* 1 2 3 4 5 6 7 8 9 10 11 12 Data.HashSet del paquet unordered-containers(anglès)
* 1 2 3 4 5 6 7 8 9 10 11 Data.HashMap.Lazy del paquet unordered-containers(anglès)
* 1 2 3 4 5 6 7 8 9 10 11 12 13 Data.Sequence(anglès)
* 1 2 3 4 5 6 Data.Array.Repa(anglès)
* ↑ paquet Vector(anglès)
* ↑ Haskell numèric: Guia sobre Vector(anglès)
* ↑ Famílies de tipus (anglès)
* 1 2 http://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html
* ↑ El paquet mono-traversable(anglès)
* 1 2 3 MonoPointed(anglès)
* 1 2 3 MonoFunctor(anglès)
* ↑ MonoZip(anglès)
* 1 2 3 4 5 MonoFoldable
* 1 2 MonoTraversable(anglès)
* 1 2 3 4 5 tipus NonNull t(anglès)
* 1 2 3 4 classe SemiSequence(anglès)
* 1 2 3 4 5 classe IsSequence(anglès)
* ↑ Textual(anglès)
* ↑ Utf8(anglès)
* 1 2 SetContainer(anglès)
* 1 2 3 4 5 IsSet(anglès)
* 1 2 3 4 5 IsMap(anglès)
* 1 2 3 4 5 6 7 8 9 paquet bytestring-trie(anglès)
* ↑ Data.DList(anglès)
* ↑ Demistifying DList's(anglès)
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Data.Heap del paquet heap(anglès)
* ↑ paquet semigroups
* ↑ mòdul Data.Semigroup(anglès)
* 1 2 3 4 5 Data.List.NonEmpty(anglès)
* 1 2 3 4 5 6 7 8 9 Data.Maybe
* 1 2 3 4 5 6 7 Data.Either
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Data.List
* 1 2 3 4 5 6 7 8 9 10 11 Data.ByteString(anglès)
* 1 2 3 4 5 6 7 8 9 10 11 12 13 Data.Text(anglès)
* 1 2 Data.Text - Tipus intern del Arxivat 2013-06-15 a Wayback Machine.(anglès)
* 1 2 3 4 5 Data.Monoid(anglès)
* 1 2 3 4 5 6 7 8 9 Data.Array
* ↑ Data.Array.Unboxed
* 1 2 3 4 5 6 7 8 9 10 Data.Vector(anglès)
* 1 2 3 4 5 Data.Vector.Mutable(anglès)
* 1 2 3 4 5 6 Data.Array.IArray
* 1 2 3 4 5 6 Data.Array.MArray
* 1 2 3 4 5 6 7 8 Data.Tree
* 1 2 3 paquet mono-traversable
* 1 2 3 4 Data.Foldable
* ↑ Data.Map.(!)(anglès)
* ↑ HaskellWiki Debugging(anglès)
* 1 2 3 Data.Functor
* ↑ Data.List.union
* ↑ Control.Monad.mfilter
* ↑ Data.Sequence.breakl(anglès)
* ↑ La classe Show(anglès)
* ↑ La classe Read(anglès)
* ↑ La classe Data(anglès)
* ↑ La classe Generic(anglès)
* ↑ La classe NFData(anglès)
* ↑ La classe Binary(anglès)
* ↑ paquet mono-traversable(anglès)
* ↑ Data.Traversable
* ↑ Functor-Applicative-Monad Proposal(anglès)
* ↑ HaskellWiki - MonadPlus(anglès)
* ↑ HaskellWiki - MonadPlus reform proposal(anglès)
* ↑ Data.Binary(anglès) Serialització
* ↑ Control.DeepSeq(anglès)
* 1 2 Data.Data(anglès)
* ↑ Data.Eq(anglès)
* ↑ Data.Ord(anglès)
* ↑ Text.Show(anglès)
* ↑ Text.Read(anglès)
* ↑ Data.Binary.Generic(anglès)
* ↑ Extensió NumDecimals Arxivat 2018-08-21 a Wayback Machine.(anglès)
* 1 2 3 Data.String
* 1 2 Extensió OverloadedStrings(anglès)
* 1 2 La classe IsList(anglès)
* 1 2 Extensió OverloadedLists(anglès)
* ↑ El paquet bytestring(anglès)
* ↑ HaskellWiki - Orphan instance(anglès)
* ↑ Opcions i variables predefinides per al CPP Arxivat 2014-02-02 a Wayback Machine.(anglès)
* ↑ Compilació condicional Arxivat 2014-02-02 a Wayback Machine.(anglès)
* ↑ GHC version numbering policy Arxivat 2016-05-09 a Wayback Machine.(anglès) Política de numeració de versions de GHC
* ↑ HaskellWiki - Compatibility modules
* ↑ Alex: A lexical analyser generator for Haskell(anglès)
* ↑ Happy: The Parser Generator for Haskell(anglès)
* ↑ hsc2hs(anglès)
* ↑ Writing Haskell interfaces to C code: hsc2hs(anglès)
* ↑ Haskell FFI tutorial example(anglès)
* ↑ GreenCard - generador de codi d'enllaç amb biblioteques en C(anglès)
* ↑ GreenCard: a foreign language interface for Haskell
* ↑ https://github.com/haskell/c2hs c2hs
* ↑ Type Holes(anglès)
* ↑ Depuració(anglès)
* 1 2 HaskellWiki - Stack overflow
* ↑ HIW 2012. Simon Marlow: Why can't I get a stack trace?(anglès)
* ↑ Finding the needle: Stack Traces for GHC - Tristan Allwood, Simon Peyton-Jones and Susan Eisenbach(anglès)
* ↑ HaskellWiki - Stack trace(anglès)
* ↑ errorWithStackTrace de GHC.Stack (anglès)
* ↑ GHC - RTS Configurations (anglès)
* ↑ GHC - Opcions de perfilat Arxivat 2014-07-14 a Wayback Machine. (anglès)
* ↑ Stack Traces in GHCi(anglès)
* ↑ Catching Exceptions(anglès)
* ↑ El paquet exceptions aporta excepcions no limitades a la mònada IO(anglès)
* ↑ «GHC users guide - The GHCi Debugger». Arxivat de l'original el 2011-03-03. [Consulta: 10 maig 2014].
* ↑ No more exceptions: debugging Haskell code with GHCi(anglès)
* ↑ El fitxer ".ghci" Arxivat 2014-07-25 a Wayback Machine.(anglès)
* ↑ Notes de la versió 7.10.2(anglès)
* ↑ Special implicit parameters Arxivat 2015-09-05 a Wayback Machine.(anglès) Pila de crides com a paràmetre implícit
* ↑ la biblio. file-location(anglès)
* ↑ HaskellWiki - Debugging - Locating a failure in a library function(anglès)
* ↑ La biblioteca Safe(anglès)
* ↑ GHC flag reference Arxivat 2014-09-18 a Wayback Machine.(anglès)
* ↑ La biblio classy-prelude(anglès)
* ↑ La biblio mono-traversable(anglès)
* ↑ El paquet loch-th aporta un mecanisme per informar de les crides a les assercions fallides(anglès)
* ↑ force del paquet deepseq permet avaluar els components d'una dada
* ↑ Mòdul Debug.Trace(anglès)
* ↑ EventLog Tracing(anglès)
* ↑ HaskellWiki EventLog(anglès)
* 1 2 GHC users guide - RTS EventLog Arxivat 2010-04-02 a Wayback Machine.(anglès)
* ↑ Variables globals(anglès)
* ↑ La mònada Reader
* ↑ HaskellWiki - Top level mutable state
* ↑ Una solució al problema de les configuracions.
* ↑ paquet Seal-module
* ↑ Implicit configurations
* 1 2 3 4 System.IO.Unsafe (anglès)
* 1 2 IO inside: The dark side of the IO Monad(anglès)
* ↑ Hack - In computer science(anglès)
* ↑ The Reader monad(anglès)
* ↑ Retainer profiling
* ↑ La biblioteca deepseq(anglès)
* ↑ El paquet deepseq-th(anglès)
* ↑ HaskellWiki - Memory leak(anglès)
* ↑ .Edward Z. Yang - Space leak zoo(anglès)
* ↑ Profiling (ajustatge)(anglès)
* ↑ An Introduction to Cabal sandboxes Arxivat 2014-09-25 a Wayback Machine.(anglès)
* ↑ HaskellWiki - Stackage(anglès)
* ↑ El servidor Stackage
* ↑ LTS Haskell: Versionar l'ecosistema(anglès)
* ↑ stackage.org - LTS actual(anglès)
* ↑ What's the point of Stackage LTS?(anglès)
* ↑ yesodweb.com - Stable, Vetted Hackage(anglès)
* ↑ FPComplete Haskell Center Arxivat 2014-07-16 a Wayback Machine.(anglès)
* ↑ haskellstack.org(anglès)
* ↑ Sooner: producing a program more quickly Arxivat 2017-08-22 a Wayback Machine.(anglès)
* ↑ Faster: producing a program that runs quicker Arxivat 2017-08-22 a Wayback Machine.(anglès)
* ↑ Smaller: producing a program that is smaller Arxivat 2017-08-22 a Wayback Machine.(anglès)
* ↑ Thriftier: producing a program that gobbles less heap space Arxivat 2017-08-22 a Wayback Machine.(anglès)
* ↑ «Tipus unboxed (allotjament directe) - Restriccions». Arxivat de l'original el 2013-08-09. [Consulta: 12 desembre 2013].
* ↑ Tipus amb allotjament directe (ang:unboxed) i primitius Arxivat 2013-08-09 a Wayback Machine. (anglès)
* ↑ «Pragma UNPACK». Arxivat de l'original el 2014-01-25. [Consulta: 12 desembre 2013].
* ↑ Notes de la versió 7.8.1
* ↑ «Tuples unboxed.». Arxivat de l'original el 2013-08-09. [Consulta: 12 desembre 2013].
* ↑ Pragmes del Haskell98(anglès)
* ↑ haskellWiki - Safe Haskell(anglès)
* ↑ GHC users guide - Safe Haskell Arxivat 2016-03-14 a Wayback Machine.(anglès)
* ↑ Compilador Frege
* ↑ Referència del llenguatge Frege(anglès)
* ↑ HaskellWiki - The JavaScript Problem(anglès)
* 1 2 Haste: Running Haskell in the Browser
* ↑ Try Haste(anglès)
* ↑ Haste report - Towards a Declarative Web(anglès)
* ↑ GitHub - valderman/haste-compiler(anglès)
* ↑ GitHub - ghcjs(anglès)
* ↑ GHCJS, Concurrent Haskell in the Browser(anglès)
* ↑ GHC - Procés de generació de codi(anglès)
* ↑ Paquet hlint que genera el programa del mateix nom(anglès)
* ↑ Cabal-dev - Sandboxed development builds for Haskell Arxivat 2011-01-28 a Wayback Machine.(anglès)
* ↑ cabal-meta (anglès)
* ↑ cabal-ghci (anglès)
* ↑ yackage (anglès)
* ↑ Threadscope
* ↑ «Ajustatge fi del paral·lelisme amb ThreadScope». Arxivat de l'original el 2009-12-29. [Consulta: 7 setembre 2009].
* ↑ Haskell Program Coverage Arxivat 2009-10-25 a Wayback Machine.(anglès) eina que mostra quin codi no s'ha executat mai i condicions sempre certes o sempre falses
* ↑ Hp2any - Obtenció del perfil d'ús de memòria(anglès)
* ↑ Eines de desenvolupament de programes(anglès)
* ↑ Liquid Types(anglès)
* ↑ HaskellWiki - Liquid Haskell(anglès)
* ↑ LiquidHaskell README(anglès)
* ↑ Refinement types Arxivat 2014-12-05 a Wayback Machine.(anglès)
* 1 2 Refinement types for Haskell(anglès)
* ↑ L'estàndard SMT(anglès)
* ↑ Real world Liquid(anglès)
* ↑ LiquidHaskell Blog
* ↑ MathSAT(anglès)
* ↑ Guia d'Opcions de l'intèrpret d'ordres en Haskell Arxivat 2013-09-29 a Wayback Machine.(anglès)
* ↑ API System.Console.GetOpt amb exemples(anglès)
* ↑ Neil Mitchell - Intèrpret d'ordres, exemples d'arguments(anglès)
* ↑ The Exception type (anglès)
* ↑ GHC extra - Seleccions estil SQL a les llistes Arxivat 2005-11-29 a Wayback Machine.(anglès)
* ↑ paquet vector-algorithms(anglès)
* ↑ El paquet unordered-containers de la plataforma Haskell, aporta HashMap i HashSet(anglès)
* ↑ Haskell wiki - Regular expressions(anglès)
* ↑ paquet aeson(anglès)
* ↑ Data.Tree(anglès)
* ↑ Gtk2hs(anglès)
* ↑ Per què serveix el símbol ___gxx_personality_v0(anglès)
* ↑ WxHaskell(anglès)
* ↑ wxWidgets(anglès)
* ↑ Van Laarhoven - CPS Functional References(anglès)
* ↑ Eduard Kmett - Lens wiki - Overview(anglès)
* ↑ The lens library(anglès)
* ↑ HaskellWiki - Lens(anglès)
* ↑ El paquet lens(anglès)
* ↑ Haskell wiki - Dependent type (anglès)
* ↑ Haskell wiki - Type arithmetic(anglès)
* ↑ Paquet type-level-natural-number(anglès)
* ↑ Paquet numtype-tf(anglès)
* ↑ dimensional-tf(anglès)
* ↑ Haskell Trac - TypeNats(anglès)
* ↑ GHC Plugins(anglès)
* ↑ paquet type-nat-solver al GitHub(anglès)
* ↑ TypeNats example(anglès)
* ↑ Estàndard Haskell2010 - Signed integer types(anglès)
* ↑ GHC floatRange(anglès)
* 1 2 Mòduls mútuament recursius(anglès)

## Vegeu també

* Mònada (programació funcional)
* Fletxa (programació funcional)
* L'intèrpret Hugs
* Frege (llenguatge de programació) - lleng. quasi-Haskell per a la màquina virtual Java. Actualment eta-lang.org el supera, doncs no altera el llenguatge haskell (utilitza un GHC modificat anomenat eta).
* Idris (llenguatge de programació) - lleng. quasi-Haskell amb tipus dependents de valors, tipus com a objectes de primer ordre, i aportació de proves inductives (demostració de teoremes). Avaluació estricta.
* Elm (llenguatge de programació) - lleng. quasi-Haskell de programació funcional reactiva amb sortida a JavaScript, d'avaluació estricta per la generació d'entorns gràfics que varien segons els esdeveniments i canvis de valor.

## Enllaços externs

* Pàgina oficial de GHC (anglès)
* GHC - Guia d'usuari (anglès)
* El Run Time System del GHC (anglès)
* Cadarache-2012 Arxivat 2012-12-25 a Wayback Machine. (anglès) Diapos. de presentacions de Simon Marlow: 1. Parallel haskell, 2. La mònada Par, 3. Concurrent Haskell, 4. STM, 5 Server apps., 6. Cloud Haskell, 7. Accelerate