9
votes

Haskell - Obtenez Nth Element sans "!!"

Bonjour, j'ai besoin d'obtenir le nième élément d'une liste mais sans utiliser le !! opérateur. Je suis extrêmement nouveau à Haskell, donc j'apprécierais si vous pouvez répondre plus en détail et non seulement une ligne de code. C'est ce que j'essaie pour le moment:

nthel:: Int -> [Int] -> Int
nthel n xs = 0
let xsxs = take n xs
nthel n xs = last xsxs


1 commentaires

let xsxs = prendre n xs - Qu'est-ce que c'est censé faire?


4 Réponses :


13
votes

Il y a beaucoup de choses qui sont un peu désactivées ici, xxx pré>

est techniquement correcte, vraiment nous voulons p> xxx pré>

afin que nous puissions l'utiliser Sur les listes de tout (facultatif) p> xxx pré>

Ce que vous venez de dire est "Peu importe ce que vous donnez à nthel code> retour 0". Ce qui est clairement faux. p> xxx pré>

Ce n'est tout simplement pas légal Haskell. laisse ... code> est une expression, il ne peut pas être utilisé de toplevel. P>

de là, je ne suis pas vraiment sûr de ce que c'est censé faire. p>

Peut-être que cela vous aidera à vous mettre sur la bonne voie p> xxx pré>

essayez de remplir dans le ??> code> avec votre meilleure hypothèse Et je suis heureux d'aider à partir de là. p>

Vous pouvez également utiliser la syntaxe "motif correspondant" de Haskell. J'explique comment vous pouvez faire cela avec des listes ici . P>

qui change de novateur à p >

nthelem n [] = <???> -- error case, empty list
nthelem 0 (x:xs) = x --bind x to the first element, xs to the rest of the list
nthelem n (x:xs) = <???> -- recursive case


12 commentaires

"De là, je ne suis pas vraiment sûr de ce que c'est censé faire." J'essaie de couper la liste jusqu'au nième élément, puis de prendre le dernier (I.e. Nth Element). Je pensais que ce serait le moyen le plus simple de prendre le nième élément sans !!. Si vous savez que quelque chose de plus simple n'hésitez pas à le partager. Quoi qu'il en soit, merci pour la réponse!


Je l'ai fait, c'est ce que tout le fond du poteau est


C'est ce que j'ai du mal à faire - comment mettre à la fois prendre et enfin dans le . Désolé pour les questions muettes mais je fais Haskell pendant quelques heures.


Vous n'avez pas besoin de prendre et Dernier , vous pouvez le faire simplement à l'aide de la récursion et de la tête et queue . Et ne vous inquiétez pas de poser une question, Haskell est difficile au début


J'ai pensé à la récursion, mais ce que j'ai lutte pour mettre en œuvre deux fonctions (tête et queue) à la fois. Je n'ai utilisé que sur une heure jusqu'à maintenant et je ne suis pas sûr de la syntaxe.


Oui, mais ce ne serait-il pas la même utilisation de la tête et de la queue et de prendre et durer, juste l'inverse? Je veux dire dans les deux cas, vous faites partie du texte, puis un certain élément de cette partie?


Ici, je vais me remplir un pour vous, voyez si cela aide


Et d'appliquer une fonction à la queue d'une liste do Func (Liste de la queue)


Conseil tête et queue et motif correspondant sur n'importe quoi au lieu de x: xs = -1


@Philipjf Il a commencé Haskell "il y a quelques heures" Je ne vais pas lui apprendre quelque chose qu'il ne comprend pas. Il ne comprend même pas la syntaxe des fonctions, vous voulez que j'utilise le motif correspondant? De plus, il fait les blancs complètement triviaux


Eh bien, la correspondance des motifs est jolie fondation, et je ne pense pas que Nthelem 0 (x: xs) = x est beaucoup plus difficile à lire que ce que vous avez ( nthelem n (x: xs ) = Nthelem (n-1) XS comme cas final). Je pense que nous devrions enseigner le modèle correspondant avant tête et queue .


Je suis respectueusement en désaccord, mais cela ne vaut pas la peine de discuter plus de 2 Rep :) J'ai été édité pour inclure la correspondance des motifs cependant



9
votes

Je pense que vous pensez que ceci: xxx

... que vous pouvez simplifier comme: xxx


2 commentaires

Exactement! Merci! Vous avez tous deux, votez-vous parce que ma note est trop faible pour le faire moi-même. :)


Cela ne fonctionne que si la liste est au moins aussi longue que l'indice souhaité, à titre de retour à N ou la longueur de la liste, donc Nthel 15 de "ABC" renvoie "C" au lieu de rien.



1
votes

Je pense que vous devriez éviter d'utiliser Dernier dans la mesure du possible - les listes sont faites à utiliser à partir de la "extrémité avant", non du dos. Ce que vous voulez, c'est vous débarrasser des premiers n éléments, puis obtenir la tête de la liste restante (bien sûr, vous obtenez une erreur si le reste est vide). Vous pouvez l'exprimer directement comme suit: xxx

ou plus court: xxx

ou légèrement fou: xxx < / pré>


0 commentaires

1
votes

Comme vous savez que la liste n'est pas indexée naturellement, mais elle peut être surmontée en utilisant des conseils communs.

Essayez dans ghci, zip [0 ..] "Bonjour" , Qu'attends "code> zip [0,1,2]" Bonjour " ou zip [ 0..10] "Bonjour" ?
À partir de cette observation, nous pouvons maintenant facilement obtenir un moyen d'indexer notre liste.
De plus, une bonne illustration de l'utilisation de la paresse, un bon indice pour votre processus d'apprentissage.

Ensuite, en fonction de la correspondance et de l'utilisation de motifs, nous pouvons fournir un algorithme efficace.

  1. Gestion des cas de liaison (liste vide, index négatif).
  2. Remplacez la liste par une version indexée à l'aide de la fermeture à glissière.
  3. Appelez une conception de la fonction d'assistance pour traiter récursivement notre liste indexée.

    MAINTENANT pour la fonction d'assistance, la liste ne peut pas être vide, puis nous pouvons moquer la correspondance naïvement et,

    • Si notre indice est égal à N, nous avons un gagnant
    • sinon, si notre élément suivant est vide, c'est sur
    • ailleurs, appelez la fonction d'assistance avec l'élément suivant.

      Remarque supplémentaire, car notre fonction peut échouer (Liste vide ...) Cela pourrait être une bonne chose à envelopper notre résultat en utilisant le type peut-être.

      Mettre tout cela ensemble, nous finissons par. xxx


0 commentaires