[JAVA] À propos de l'explication sur le type de fonction

en premier

Je m'intéresse moi-même aux langages fonctionnels et visite divers sites Certains sites décrivent soigneusement les mérites des langages fonctionnels et vous font penser que "les langages fonctionnels sont bons", tandis que d'autres disent "bien, cela ne vous fait pas ressentir les mérites des langages fonctionnels". Ce que je voudrais écrire à propos de cette époque, ce sont les caractéristiques d'un "site qui ne vous fait pas ressentir les mérites des langages fonctionnels".

Exemple de site spécifique

L'exemple est Site Code IQ. Le but du site ci-dessus semble être que le traitement du tableau soit écrit dans le langage de type instruction (langage C) et le langage de type de fonction (Haskell), et le langage de type de fonction (Haskell) est facile à comprendre en comparant les deux.

Qu'est-ce qui ne va pas

Je conviens sincèrement que la description du langage fonctionnel (Haskell) est très concise, mais je pense personnellement qu'il y a quelques problèmes avec la logique du langage C donné comme exemple du langage impératif. .. Je ne suis donc pas sûr que ce que l'on dit être le bénéfice du dernier langage fonctionnel (Haskell) sur le site en profite vraiment. Par exemple, si réduire et cartographier, qui sont considérés comme les mérites du langage fonctionnel sur ce site, ne demandent pas beaucoup de temps et d'efforts lorsqu'ils sont mis en œuvre dans le langage pédagogique, on ne peut pas dire qu'il y a un vrai mérite.

Problèmes avec l'exemple de programme

Ci-dessous, je vais énumérer les problèmes de l'exemple de programme que j'ai personnellement ressenti.

Problème 1 Je ne sais pas ce que signifie le nom de la variable

Que signifie vraiment i ou N dans l'exemple de programme? Je ne savais pas ce que représentaient les noms de variables, donc je ne pouvais pas comprendre à quoi servait la logique simplement en lisant le programme. À tout le moins, i devrait être compteur et N devrait être ARRAY_LIMITTED_NUMBER pour clarifier le rôle de la variable.

Problème 2 La méthode de déclaration d'un tableau a changé.

Si vous utilisez un initialiseur lors de l'initialisation d'un tableau, pourquoi ne pas définir le nombre d'éléments dans le tableau?

Problème 3 L'accès à la baie est étrange

Il peut y avoir des malentendus en ce qui concerne l'étrangeté, mais n'est-il pas plus facile d'écrire le processus en utilisant des pointeurs plutôt que des indices pour accéder aux tableaux? Si vous y accédez avec un pointeur, au moins la variable i devrait être inutile

Problème 3 Structure des données du tableau

N'est-ce pas mieux qu'un problème? C'est une proposition. Il semble préférable d'introduire NULL pour représenter la fin du tableau De cette façon, vous n'avez pas à comparer l'indice avec le nombre maximum d'éléments dans le tableau lors de la détermination de la condition de sortie de la boucle. Eh bien, dans ce cas, il y a un problème de savoir quoi faire si NULL est inséré au milieu du tableau, mais tant que vous utilisez le langage C, vous devez créer des règles pour la fin du tableau. L'exemple de programme utilise également define pour définir secrètement le nombre maximum d'éléments dans le tableau comme 5.

Problème 4 Concernant le fait que le traitement et le contrôle des données sont mélangés

Dans le programme d'origine, le contrôle des données (traitement en boucle) et le traitement des données (simulation de serpent et de grenouille) sont effectués en un seul endroit. Mais n'est-ce pas contraire à la programmation structurée qui a été dite pendant des décennies avant les langages fonctionnels? Si vous faites du développement moderne, quel que soit le langage que vous utilisez, le contrôle et le traitement des données doivent être découpés en fonctions distinctes.

Source de langage C spécifique

Ci-dessous, je publierai le code du langage C que j'ai amélioré

Source améliorée

sample.c


#include "stdafx.h"

//Calculez le nombre de grenouilles survivantes
int calc(int snakes, int flogs) {
	if (flogs >= snakes) return flogs - snakes;
	else return 0;
}

//Une fonction qui manipule un tableau de grenouilles et de serpents
int execute(int snakes[], int flogs[]) {
	int survivors = 0; //Nombre total de grenouilles survivantes
	while (true) {
		//Échapper à la boucle lorsque vous atteignez la fin du tableau
		if (*snakes == NULL) break;
		survivors += calc(*snakes++, *flogs++);
	}
	return survivors;
}

int main()
{
	int snakes[] = { 5,4,3,2,1,NULL };//serpent
	int flogs[] = { 7,6,1,2,2 ,NULL };//Grenouille
	printf("Nombre de grenouilles qui ont survécu%5d", execute(snakes, flogs));
	getchar();
	return 0;
}

En utilisant la déclaration de prototype, nous avons également permis de réduire et de mapper le comportement des langages fonctionnels.

Source améliorée (carte, version réduite)

sample.c


#include "stdafx.h"
typedef int(*FUNCPTR)(int a, int b);

//Une fonction qui manipule un tableau de grenouilles et de serpents
//Passez un pointeur de fonction à FUNCPTR qui simule la compétition de survie entre les grenouilles et les serpents.
int zip_and_reduce(int snakes[], int flogs[],FUNCPTR func) {
	int survivors = 0; //Nombre total de grenouilles survivantes
	while (true) {
		//Échapper à la boucle si NULL apparaît dans le tableau
		if (*snakes == NULL) break;
		survivors += func(*snakes++, *flogs++);
	}
	return survivors;
}

//Calculez le nombre de grenouilles survivantes
int calc(int snakes, int flogs) {
	if (flogs >= snakes) return flogs - snakes;
	else return 0;
}

//Calculez le nombre lorsque les grenouilles et les serpents coexistent
int calc_kyouzon(int snakes, int flogs) {
	return flogs + snakes;
}

int main()
{
	int snakes[] = { 5,4,3,2,1,NULL };//serpent
	int flogs[] = { 7,6,1,2,2 ,NULL };//Grenouille
	printf("Nombre de grenouilles qui ont survécu%5d", zip_and_reduce(snakes, flogs,&calc));
	printf("Nombre lorsque les serpents et les grenouilles coexistent%5d", zip_and_reduce(snakes, flogs, &calc_kyouzon));
	getchar();
	return 0;
}

Je publierai également le Ver implémenté en Java.

sample.java


package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class MyTest {
    public static void main(String args[]){
		List<Integer>snakes = new ArrayList<Integer>();
		Collections.addAll(snakes, 1,2,3,20);
		List<Integer>flogs = new ArrayList<Integer>();
		Collections.addAll(flogs, 10,2,3,4,5);
		System.out.println(execute(snakes,flogs));
	}
	//Fonctions à exposer à l'extérieur
	//Passez les arguments du serpent et de la grenouille comme arguments
	public static int execute(List<Integer>snaeks,List<Integer>flogs){
		//La première valeur totale est 0
		return execute(snaeks.iterator(),flogs.iterator() ,0);
	}
    //Fonctions utilisées en interne
	//Iterator<Integer>snakes :Type de dénombrement des serpents
	//Iterator<Integer> :type d'énumération des flogs
	//sum :Valeur totale des flogs
	private static int execute(Iterator<Integer>snakes,Iterator<Integer>flogs ,int sum){
		//Lorsqu'il n'y a pas de serpents ou de grenouilles, le processus est terminé
		if(!snakes.hasNext() && !flogs.hasNext())return sum;
		//Continuer le traitement si un serpent ou une grenouille est présent
		else return execute(snakes,flogs,sum + calc(ifExists(snakes),ifExists(flogs) ) );
	}	
	//Trouvez le nombre de grenouilles
	//Renvoie le nombre de grenouilles moins le nombre de serpents lorsqu'il y a plus de grenouilles que de serpents
	//serpents int: nombre de serpents
	//int flogs: nombre de grenouilles
	private static int calc(int snakes,int flogs){
		if(snakes<= flogs) return flogs - snakes;
		else return 0;
	}
    //Renvoie l'élément si l'énumérateur en a un, sinon renvoie 0
	private static int ifExists(Iterator<Integer>ite){
		if(ite.hasNext())return ite.next();
		else return 0;
	}
}

À la fin

En regardant la source de langue impérative améliorée et la source de langue fonctionnelle, je pense que chaque personne pense différemment. Je ne suis pas très doué pour les langages fonctionnels (Haskell),

--Facile à gérer les tableaux par rapport au langage C

Je sens qu'il y a un mérite

Au contraire, que diriez-vous de l'explication qu'il est pratique parce que vous pouvez utiliser réduire et cartographier? je pense

Recommended Posts

À propos de l'explication sur le type de fonction
À propos de la méthode
À propos du paquet
Sortie sur la méthode, partie 2
À propos de la classe StringBuilder
Commentaire: à propos de l'interface
À propos du pipeline d'actifs
À propos de la double fonction -java
À propos de l'opérateur ternaire
null spécifie le type
À propos de la méthode de longueur
À propos du module Kernel
À propos de la méthode cartographique
À propos de la méthode des ancêtres
[Sortie] À propos de la base de données
À propos de la méthode to_s.
À propos de la gestion de Null
A propos de la spécification du chemin JAXRS
Essayez le type fonctionnel en Java! ①
[Swift] Résumé du type Bool
À propos de la description de Docker-compose.yml
À peu près la même et la même valeur
À propos du cycle de vie Android
À propos du langage de programmation Crystal
Prise en compte de la méthode des temps
Explication sur l'objet Ruby String
À propos du comportement de ruby Hash # ==
À propos des bases du développement Android
À propos des méthodes equals () et hashcode ()
À propos du symbole <%%> dans Rails erb
Explication de l'ordre des itinéraires ferroviaires
À propos de la bande d'applications de partage d'informations
À propos de l'environnement de développement actuel (Java 8)
Comprenons le type Array (Element)!
Un murmure sur la classe utilitaire
À propos du rôle de la méthode initialize
Pensez aux 7 règles d'Optionnel
Explique les objets Ruby Array
Comprenons le type facultatif (enveloppé)!
À propos du niveau de journalisation de java.util.logging.Logger