Tout d'abord, nous ne parlons pas de méthodes: on parle de fonctions. Il y a quelque chose dans clojure que vous pourriez appeler une méthode mais c'est différent d'une fonction. Si vous arrêtez d'utiliser le jargon OO, vous perdrez également le style de pensée OO.
Ce que vous essayez de faire est possible. Vous souhaitez fondamentalement créer une nouvelle fonction avec le nom dupx
dans la fonction dupseqx
. Ce que vous faites en ce moment est de créer une fonction et ensuite de la jeter (vous ne faites rien avec la valeur de retour et seulement le dernier formulaire d'une fonction est renvoyé). Comme une fonction est comme n'importe quelle autre valeur, vous pouvez utiliser le même mécanisme qu'avec n'importe quelle autre valeur: créer une "variable" locale. Quel est le mécanisme pour cela? Il est une liaison locale et cela fonctionne comme celui-ci (le nom dans la fn est juste pour que vous pouvez appeler à partir de lui-même, il n'a pas besoin d'être le même que le nom let
liØe):
(let [dupx (fn dupx [v x]
(if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))
Avis que j'ai corrigé d'autres choses.
Une courte forme de cette (fixation double nom laideur):
(letfn [(dupx [v x] (if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))
Ok dans tout entre « (nous allons [...] » Et la mise en correspondance ")" nous avons maintenant une fonction dupx
Alors maintenant, le reste de votre code fonctionne.
(fn dupSeqX [aseq x]
(letfn [(dupx [v x] (if (= x 1) (list v) (cons v (dupx v (dec x)))))]
(reverse (reduce #(concat %1 (dupx %2 x)) '() aseq))))
Ce code peut être un peu plus idiomatiques:
- Directives de codage: paramètres de nom
coll
au lieu de aseq
- Directives de codage: DoNotUseCamalCase do-it-like-ce
- Récursion lorsque vous n'en avez pas besoin est mauvais pour la performance et les grands nombres.
- Vous réinventez la roue. C'est bon d'apprendre le codage mais pas bon si vous voulez apprendre à connaître la langue et la lib standard.
Comment est-ce que j'ai écrit ceci?
D'abord le fn de base. coll
est la norme pour la fonction de nommage qui attendent des séquences.
(fn [coll times] )
Si vous lisez ceci "chaque élément d'une séquence" votre cerveau doit aller MAP. "Réplique chaque ..." est essentiellement une description de ce que vous devez mettre dans la fonction de la carte. Nous pouvons utiliser repeat
(votre fonction dubx mais avec quelques goodies supplémentaires comme ça c'est paresseux).
(fn [coll times]
(map (fn [val] (repeat times val)) coll))
Il reste un problème (provenant du koan). Il veut un seq en arrière, pas une séquence dans une séquence pour chaque élément. Cela signifie que nous devons concaténer le résultat ensemble.
(fn [coll times]
(apply concat (map (fn [val] (repeat times val)) coll)))
Vous verrez souvent le modèle (apply concat (map ....))
. Il y a une meilleure fonction pour cela dans la bibliothèque standard, appelée mapcat
, et je vais faire la fonction interne dans la syntaxe courte.
(fn [coll times]
(mapcat #(repeat times %) coll))
Hope that helps!
Voici quelques conseils. Je pense que vous voulez dire la fonction au lieu de la méthode. De plus, les fonctions sont définies avec defn mais les fonctions anonymes (lamdba) sont définies avec fn. Vous confondez les deux. En outre, si vous avez besoin d'une fonction locale dans la portée de votre fonction externe, utilisez let ou letfn. –