2017-10-15 25 views
0

Comment créer une fonction map, une fonction d'ordre supérieur, en rouge. Il devrait prendre un bloc et une fonction comme arguments et appliquer la fonction envoyée à chaque membre du bloc. J'ai essayé code suivant:Création d'une fonction de carte en langage rouge

Red [] 
mapfn: function[blk sfn][ 
    outblk: copy [] 
    foreach i blk[ 
     append outblk (sfn i) ] 
    outblk ] 

; to test: 
myblk: [" this " " is " " a " " line " "for" " testing " " only "] 
probe mapfn myblk 'reverse 
probe mapfn myblk 'trim 

Mais il ne fonctionne pas - il envoie simplement de nouveau le bloc d'origine sans le modifier ou de donner un message d'erreur. Comment cela peut-il être corrigé?

Répondre

0

Dans Rebol vous avez la fonction mezzanine appliquer

>> help apply 
USAGE: 
    APPLY func block /only 

DESCRIPTION: 
    Apply a function to a reduced block of arguments. 
    APPLY is a function value. 

ARGUMENTS: 
    func -- Function value to apply (Type: any-function) 
    block -- Block of args, reduced first (unless /only) (Type: block) 

REFINEMENTS: 
    /only -- Use arg values as-is, do not reduce the block 

(SPECIAL ATTRIBUTES) 
    throw 

Voir la source appliquer.

Tant que Red n'a pas natif appliquer vous pouvez écrire votre propre fonction de mappage par exemple

mapfn: function[blk sfn][ 
    outblk: copy [] 
    foreach i blk[ 
     append outblk sfn copy i 
    ] 
    outblk 
] 

Obtenez la fonction avec: functionname

>> myblk: [" this " " is " " a " " line " "for" " testing " " only "] 
== [" this " " is " " a " " line " "for" " testing " " only "] 
>> probe mapfn myblk :reverse 
[" siht " " si " " a " " enil " "rof" " gnitset " " ylno "] 
== [" siht " " si " " a " " enil " "rof" " gnitset " " ylno "] 
>> probe mapfn myblk :trim 
["this" "is" "a" "line" "for" "testing" "only"] 
== ["this" "is" "a" "line" "for" "testing" "only"] 
>> 

Une alternative et une meilleure manière que vous ne pouvez pas copier tous les types de données sont par exemple

mapfn: function[blk sfn][ 
    collect [ 
     foreach i blk[ 
      keep sfn i 
     ] 
    ] 
] 

et appeler la fonction de cette façon si aucune ne veulent pas modifier l'original

mapfn newblk: copy/deep myblk :reverse 
+0

Pourquoi couper montrant également des chaînes renversées? – rnso

+0

J'ai changé la réponse. ** reverse ** et ** trim ** fonctionnent sur la série originale et la modifient. Vous devez donc utiliser une copie de la série sur laquelle vous travaillez. – sqlab