9
votes

Types à Haskell

Je suis un peu nouveau à Haskell et j'ai du mal à comprendre comment des types dédurés et de telles œuvres.

foldr :: (a -> b -> b) -> b -> [a] -> b
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl1 :: (a -> a -> a) -> [a] -> a


9 commentaires

Connaissez-vous le concept de currying?


Je crois que c'est le concept de faire des fonctions multi-arguments à prendre seulement 1 argument. quelque chose comme f (x, y) = (f y) o (g x)?


Vous pouvez trouver le type de quelque chose avec la commande T: Thiki dans GHCI (coquille HASKELL interactive): >>: T pli de carte Pluvier carte :: [B] -> [B -> B] -> [B]


Qu'entendez-vous par «Comment définiriez-vous le type inféré de quelque chose ...»? Si vous déclarez le type de quelque chose, il n'a pas besoin d'être déduit.


En passant, il est considéré comme une bonne forme sur le débordement de pile pour accepter des réponses qui donnent une solution correcte. Vous avez posé six questions jusqu'à présent, mais n'a accepté aucune réponse.


@camccann merci pour le conseil. Je ne savais pas ça. Je ferai ça maintenant


Il a également l'effet positif des personnes qui souhaitent vous aider, quand ils ont la chance d'obtenir un morceau de ce gâteau :)


Vous avez tous répondu très bien à la plupart de mes questions, merci! Je suppose que ma seule préoccupation est que quelque chose comme>: T pli de carte pli Plier la carte :: [a] -> [A -> A] -> [a] Comment puis-je déterminer [A] -> [A -> A] - > [a] moi-même (comme sur papier)? J'ai édité la question de la clarté.


@Linda: J'ai édité ma réponse, j'ai un coup d'œil au fond même (Dieu, il est devenu grand)


4 Réponses :


1
votes

in Haskell, une variable minuscule est une variable de type. Tandis que caractère signifie simplement char , A ou b pourrait signifier char ou < Code> BOOL ou INTEGER ou un autre type. La clé est que tout A S sera le même type. Et tout b s sera le même type.

Par exemple, carte prend comme premier argument une fonction qui prend une variable de type A et renvoie un autre type B . Alors mappe renvoie une nouvelle fonction qui prend une liste de type A . Cette nouvelle fonction renvoie une liste de type b .

supposons que vous aviez une fonction incrément qui a ajouté un à un entier. incrément de carte [1,2,3] retournerait finalement une liste [2,3,4].

la définition antérieure de carte avec le Les variables de type remplacées ressembleraient à:

Carte :: incrément -> [1,2,3] -> [2,3,4]

et incrément , btw, ressemblerait à

incrément :: Integer -> Integer

La raison pour laquelle il est écrit drôle parce que vous pouvez appliquer partiellement des fonctions. Ici, je vais faire une nouvelle fonction basée sur l'application partielle de la carte: xxx

alors vous pouvez utiliser xxx

qui produirait le même résultat


0 commentaires

10
votes

Si vous prenez l'exemple de

double :: Int -> Int
double = (*2)


0 commentaires

1
votes

Les lettres minuscules dans les déclarations de type sont variables de type strong>. Cela signifie que lorsqu'il y a un a code>, il doit s'agir du même type.

crochet (par exemple, (A -> B) code>) Les subexpressions ont tendance à signifier que la fonction accepte la fonction Une fonction comme l'une de ses paramètres. p>

Supports rectangulaires indique une liste de quelque chose. p>

donc carte code> accepte ces arguments: p>

  • (a -> b) code> une fonction qui accepte un argument li>
  • [a] code> une liste que la première fonction d'argument peut agir sur li> ul>

    et produit [b] code> une liste par conséquent. p>

    Nous pouvons décoder (.) code> de la même manière:

    • (a -> b) code> est une fonction qui accepte un seul argument li>
    • (c -> a) code> est une fonction qui produit la même typa que l'argument à la première fonction li>
    • c code> un argument du même type que la deuxième fonction utilise li> ul>

      Cependant, Haskell peut faire une chose soignée et c'est si vous omettez un argument, il renvoie une fonction qui a la signature restante. Donc (.) Code> est couramment utilisé pour les fonctions de la chaîne. P>

      disons que nous avons 2 fonctions ORD :: Char -> int code> qui prend un personnage et Retourne sa représentation entier et add32 :: int -> int code> qui ajoute 32 à son argument. p>

      Lorsque nous écrivons upcaseval = add32. ord code> La fonction UPCASEVAL a maintenant la signature upcaseval :: char -> int code> car la fonction (.) code> l'aurait laissé avec C -> b code> et nous substituons ces dans la définition de la fonction. p>

      SO Plier la carte code> devrait être comme ceci: p>

      1. PlierR code> S Premier argument est une fonction qui prend 2 arguments que carte code> est. li>
      2. Depuis que les fonctions Sortie doivent être du même type que le deuxième argument ( (A -> B -> B code>), nous voyons que dans la carte code> A = B code> li> ol>

        Ainsi, le type final sera le suivant: P>

        (b -> b) -> [b] -> [b] -> b -> [b] -> b
        


2 commentaires

Bien que j'aurais pu être confondus avec la carte de la carte - prenez-la avec un grain de sel.


Le type de Plier de la carte de pliage est [b] -> [b -> b] -> [b]



3
votes

Fonctions dans Haskell Utilisez une notation appelée Currying. Une définition comme xxx

signifie que plus est une fonction qui prend deux int s et renvoie une valeur du type le plus à droite (qui est int à nouveau). Plus en détail, Currying signifie que vous travaillez avec des fonctions partiellement appliquées qui vous permettent d'écrire du code comme xxx

identifiants minuscules dans les signatures de type indiquent un type variable qui peut être considérée comme un porte-lieu pour tout type possible.

la définition xxx

signifie donc pour tout Types A et B , carte prend une fonction de A à B et un Liste des A 'S, à partir de laquelle il produit une liste de B ' s .

prenons un exemple XXX

Nous voyons, la liste donnée est une liste de int 's, donc a = int . En outre, mappe devrait appliquer Afficher à chaque élément, qui renvoie une chaîne . Étant donné que show doit adapter le type a -> b de la définition, nous pouvons déduire que b = chaîne .

Notre expression renvoie un [b] , le résultat est donc un [string] .

Pour rendre ces signatures encore plus claires, nous pouvons l'écrire Utilisation d'une syntaxe plus verbeuse xxx

ceci maintenant indique explicitement carte est censé fonctionner avec tous les types A et B .


Pour les plis, jetez un coup d'œil sur leur Définitions . Compte tenu des connaissances ci-dessus, les signatures de type doivent être auto-expliquées lorsqu'elles sont claires ce que les fonctions sont censées faire.

Exemple: factorielle n = FLETL (*) 1 [1..n]

La signature de Plier la carte devient. xxx

Vous pouvez également obtenir ceux-ci en tapant simplement : t pli carte dans l'interpréteur Haskell (GHCI).


0 commentaires