28 votes

Quels sont les pièges de l'utilisation de FlexibleContexts et FlexibleInstances?

Étant donné que ces contextes et instances flexibles ne sont pas disponibles dans la norme Haskell, je suppose qu'il existe des problèmes potentiels lors de leur utilisation. Que sont-ils? Peuvent-ils conduire à une certaine ambiguïté, indécidabilité, chevauchement d'instances, etc.?

Il y a une question similaire qui pose seulement environ FlexibleInstances , pas FlexibleContexts , mais la réponse dit seulement "qu'il est sûr de les utiliser".

14voto

Will Ness Points 18581

Une fois, j'ai trébuché sur le suivant. Répondre à cette question, j'ai d'abord essayé ce code:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}

class (Eq a, Show a) => Genome a where
    crossover       :: (Fractional b) => b -> a -> a -> IO (a, a)
    mutate          :: (Fractional b) => b -> a -> IO a
    develop         :: (Phenotype b a)  => a -> b

class (Eq a, Show a) => Phenotype a b | a -> b where
    --  In case of Coevolution where each phenotype needs to be compared to 
    --  every other in the population
    fitness         :: [a] -> a -> Int 
    genome          :: (Genome b) => a -> b    -- here, the problem

breed parents cross mute = do
    children <- mapM (\ (dad, mom) -> crossover cross (genome dad) (genome mom)) 
                     parents
    let ch1 = map fst children ++ map snd children
    mutated <- mapM (mutate mute) ch1
    return $ map develop mutated

Et j'ai obtenu une erreur de compilation et d'une suggestion GHCi ajouter l' FlexibleContexts option. Quand je l'ai fait, elle a établi OK. Mais ce n'était pas une bonne chose à faire, que la contrainte de la déclaration introduit nouveau champ d'application pour les variables de type, et b en genome's type de signature est devenu complètement étranger à la une dans le type de classe; pourtant, FlexibleContexts a fourni une couverture pour ce.

Avec la contrainte spécifiée correctement le type le niveau de la classe,

class (Eq a, Show a, Genome b) => Phenotype a b | a -> b where
    --  In case of Coevolution where each phenotype needs to be compared to 
    --  every other in the population
    fitness         :: [a] -> a -> Int 
    genome          :: a -> b

il est passé de la compilation sans exiger de l' FlexibleContexts option.

-2voto

viorior Points 1411

Il y a plusieurs risques avec toutes les extensions:

1) ils ne seraient pas nécessaires seraient inclus dans Haskell

2) Les jeunes extensions ont généralement des bugs

FlexibleInstances et FlexibleContexts sont d'anciennes extensions et sont largement utilisées

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X