10
votes

HASKELL: Puis-je utiliser une clause WHERE après un bloc avec des opérateurs BIND (>> =)?

J'ai une question très simple. J'aimerais utiliser une clause WHERE après un bloc de code qui utilise des opérateurs de liaison, mais je reçois une erreur de compilation.

Voici un exemple simple: p>

main = do
    putStrLn "where clause test:"
    list <- return [1..10]
    print list'
        where list' = reverse list --test3.hs:5:30: Not in scope: `list'


0 commentaires

3 Réponses :


1
votes

Autant que je puisse dire, la clause WHERE n'est utilisée que dans les liaisons locales . La partie interne d'un >> (=) instruction de liaison n'est pas une liaison locale (deux types différents de liaisons dans cette phrase).

comparer avec ceci: xxx

Vous voudrez peut-être vous référer au Signaler Haskell 98 Syntaxe - Je ne sais pas combien Aidez-y.

Si je me trompe, quelqu'un me corrigera certainement, mais je suis sûr que vous ne pouvez pas utiliser une clause de l'endroit du tout dans le style que vous avez montré ci-dessus. LISTE NE SERA JAMAIS UN PLANCE D'UNE CLAUSE SIZ-VOUS Sauf si c'est un paramètre de la fonction.


3 commentaires

Une abstraction Lambda est une expression, pas une déclaration ou une liaison, bien qu'elle puisse lier de nouveaux noms ...


Whoa, qui -1'ed ça? Je pense que c'est correct, sinon aussi complet que possible.


Ce n'est pas pertinent. L'OP veut utiliser "liste", résultant du milieu d'un tas de calculs monadiques; pas une valeur qui vient de l'extérieur de la monade



11
votes

Le problème est que let - dans est une expression qui peut être utilisée dans d'autres expressions, tandis que ne peut être utilisé que sur A (Module | CLASSE DE LA CLASSE | GADT | ...) DÉCLARATION OU A (FONCTION | MOTIF) Reliure.

du Rapport HASKELL 98 sur Déclarations et liaisons ,

p | g 1 = e 1
| g 2 = e 2
...
| g m = e m
où { déclins }

est le sucre pour

p = let déclins dans
si g 1 alors e 1 sinon
si g 2 (code> e 2 sinon
...
si g m alors e m sinon erreur "modèle inégalé"

ou, simplifiant les choses en supprimant les gardes,

p = e où { déclenche }

est le sucre pour

p = let déclenche dans e

dans les liaisons de fonction et de motif. Ceci est vrai même lorsque votre e est un do { ... } construction.

Si vous voulez avoir une contraignante local à une subexpression particulière dans une expression plus grande, vous devez utiliser laisser - dans (ou simplement laisser à l'intérieur d'un faire , mais ce n'est que du sucre pour let - dans ).

Vous ne pouvez même pas écrire xxx

parce que " e où { déclins } " n'est pas une expression légale - ne peut être utilisé que dans les déclarations et les liaisons. xxx

ceci est légal (si quelque peu conçu).


3 commentaires

Pourquoi pas seulement "Let List '= Reverse List"? Dans le dernier exemple?


Merci, je devrais faire référence au rapport Haskell plus souvent lorsque j'ai des questions fondamentales sur la langue telle que celle-ci.


@NewacCT: la question de l'OP comprend déjà cette variante, qui fonctionne évidemment.



11
votes

Comme éphémique explique, vous ne pouvez pas utiliser où code> clause comme vous le faites.

L'erreur se produit car dans ce code: P>

main = do
  list <- return [1..10]
  let list' = f list
  print list'
  where
    f list = reverse list -- Consider renaming list,
                          -- or writing in point-free style


1 commentaires

Merci, votre exemple avec plus de parenthèses l'effache pour moi.