IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

Types et polymorphisme (let et fun)


Sujet :

Caml

  1. #1
    Membre du Club
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 44
    Points
    44
    Par défaut Types et polymorphisme (let et fun)
    Bonjour à tous,
    Je m'attaque à la compréhension de la gestion des types en Caml et voici quelque chose que je ne m'explique pas, peut-être pourrez-vous m'aider à comprendre :

    [EDIT]
    J'essaie d'obtenir une fonction du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f : ('a -> 'b) -> 'a1 -> 'a2 -> 'b1 * 'b2 = <fun>
    [/EDIT]

    A priori, je pensais qu'il fallait utiliser un let :

    Ici ca marche, j'utilise un let, id a été déclarée au préalable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #let fonc' = fun x -> (id x) in fun x y -> (fonc' x, fonc' y);;
    - : 'a -> 'b -> 'a * 'b = <fun>
    Ici, ca ne marche pas, pourtant j'utilise la même structure au sein de la fonction....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #let f id = let fonc' = fun x -> (id x) in fun x y -> (fonc' x, fonc' y);;
    f : ('a -> 'b) -> 'a -> 'a -> 'b * 'b = <fun>
    Merci d'avance

  2. #2
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 990
    Points
    2 990
    Par défaut Plus simplement
    Et pourquoi pas :

    Code Caml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # fun x y -> x,y;;
    - : 'a -> 'b -> 'a * 'b = <fun>
    Du même auteur: mon projet, le dernier article publié, le blog dvp et le jeu vidéo.
    Avant de poser une question je lis les règles du forum.

  3. #3
    Membre du Club
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 44
    Points
    44
    Par défaut
    Bonjour,
    Merci pour votre réponse.

    J'ai du mal m'exprimer, il faut dire que le concept n'est pas encore très clair pour moi.
    Je voudrais faire ça :
    avec ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    f : ('a -> 'b) -> 'a -> 'c -> 'b * 'd = <fun>
    ou :
    f : ('a -> 'b) -> 'a1 -> 'a2 -> 'b1 * 'b2 = <fun>
    (J'ai édité mon premier message pour mieux le préciser)

  4. #4
    Membre actif
    Avatar de Ptival
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 70
    Points : 276
    Points
    276
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f : ('a -> 'b) -> 'a -> 'c -> 'b * 'd
    Tu ne peux pas retourner un élément de type 'd si tu ne reçois pas un argument de type 'd ou une fonction qui retourne entre autres un 'd.

    Il n'y a donc pas de bonne réponse à ta question : soit tu nous expliques comment tu souhaites utiliser ta fonction ou son but, et on peut te guider, ou bien tu veux vraiment créer une fonction de ce type, et personne ne peut t'aider dans cette quête.

    En particulier, ton appel :

    semble assez suspicieux. Que doit-il retourner ? Que fait-il d'id en particulier ?

  5. #5
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Tout à fait, il te faut un moyen de retourner un 'd à partir de 'a et de 'b.

    Citation Envoyé par Ptival Voir le message
    En particulier, ton appel :

    semble assez suspicieux. Que doit-il retourner ? Que fait-il d'id en particulier ?
    Les parenthèses en moins − f id (2, 2.) − c'est tout de suite plus clair. En OCaml (et en général avec les langages construits sur le modèle de lambda-calcul), il n'y a pas de distinction entre une fonction qui prend deux arguments a et b d'une part, et une fonction qui prend un argument a et retourne une fonction qui prend un argument b d'autre part.

    Cdlt,
    -- Yankel Scialom

  6. #6
    Membre du Club
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 44
    Points
    44
    Par défaut
    Bonjour à tous,
    Merci beaucoup pour vos réponses. Voici quelques précisions sur ce que je cherche :

    J'ai cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #let func = fun a -> (true, a);;
    func : 'a -> bool * 'a = <fun>
    J'ai cette autre fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #let applicator func = fun x y -> (func x, func y);;
    applicator : ('a -> 'b) -> 'a -> 'a -> 'b * 'b = <fun>
    Donc ceci marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #applicator func 2 3;;
    - : (bool * int) * (bool * int) = (true, 2), (true, 3)
    Néanmois, la fonction func peut s'appliquer aux int mais aussi au float :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #func 1.0;;
    - : bool * float = true, 1.0
    #func 2;;
    - : bool * int = true, 2
    Donc je voudrais pouvoir faire ceci sans erreurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >applicator func 2 1.0;;
    >                  ^^
    This expression has type float,
    but is used with type int.
    Pour ça, je remarque que si l'on passe par une forme let, ça fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #let func' = fun x -> (true,x) in fun x y  -> (func' x, func' y);;
    - : 'a -> 'b -> (bool * 'a) * (bool * 'b) = <fun>
    Ce que je cherche, c'est un moyen de mélanger les deux, un peu a cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #let applicator' = let func' = fun x -> (true,x) in fun x y  -> (func' x, func' y);;
    applicator' : 'a -> 'b -> (bool * 'a) * (bool * 'b) = <fun>
    Par exemple, quelque chose équivalent à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #let applicator' func = let func' = fun x -> func x in fun x y  -> (func' x, func' y);;
    applicator' : ('a -> 'b) -> 'a -> 'a -> 'b * 'b = <fun>
    J'ai alors essayé ceci sans succès :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    let applicator' func = let func1 = fun x -> func x in let func2 = fun y -> func y in fun x y  -> (func1 x, func2 y);;
    applicator' : ('a -> 'b) -> 'a -> 'a -> 'b * 'b = <fun>
    Mais cette tentative échoue.

    voilà donc ce que j'essaie de faire...


    Merci à vous

  7. #7
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Je comprends. Ton problème (et sa solution) est décrit ici : Higher-Rank Polymorphism in OCaml [legiasoft.com].
    -- Yankel Scialom

  8. #8
    Membre du Club
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 44
    Points
    44
    Par défaut
    Bonjour,
    Merci beaucoup pour la piste de recherche, je vais regarder de ce coté.

  9. #9
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 990
    Points
    2 990
    Par défaut Tu dois utiliser 2 fois la même fonction avec des types différents
    Code OCaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    # let func a = true,a
      and applicator f g x y = f x, g y;;
     
    # applicator func func 2 1.0;;

    Ou bien te compliquer la vie avec du Higher-Rank Polymorphism
    Du même auteur: mon projet, le dernier article publié, le blog dvp et le jeu vidéo.
    Avant de poser une question je lis les règles du forum.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Les 4 types de polymorphismes existants
    Par Gugelhupf dans le forum C++
    Réponses: 2
    Dernier message: 30/05/2012, 13h09
  2. Polymorphisme, variables de type faibles
    Par boromir73 dans le forum Caml
    Réponses: 8
    Dernier message: 26/06/2007, 19h38
  3. template, polymorphisme et génération de type
    Par DEVfan dans le forum Langage
    Réponses: 16
    Dernier message: 11/01/2007, 19h07
  4. Réponses: 2
    Dernier message: 06/09/2006, 14h56
  5. [AXIS][WSDL] Type abstraits, Gestion du polymorphisme ?
    Par Cyr1c dans le forum Services Web
    Réponses: 3
    Dernier message: 05/09/2006, 09h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo