使用FlexibleContexts和FlexibleInstances有哪些陷阱?

时间:2013-08-14 10:41:35

标签: haskell ghc language-extension

由于这些灵活的上下文和实例在Haskell标准中不可用,我认为使用它们时可能存在问题。这些是什么?它们会导致一些含糊不清,不可判断,重叠的实例等吗?

有一个similar question仅询问FlexibleInstances,而不是FlexibleContexts,但答案只是说“使用它们是安全的”。

1 个答案:

答案 0 :(得分:16)

我曾经偶然发现以下情况。 Answering this question,我首先尝试了这段代码:

{-# 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

有一个编译错误和GHCi建议添加FlexibleContexts选项。当我这样做时,编译好了。但这实际上不是正确的事情,因为约束声明引入了类型变量的新范围,b的类型签名中的genome变得与类型类中的FlexibleContexts完全无关;然而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 为此提供了掩护。

在类型级别正确指定约束

FlexibleContexts

它通过编译而不需要{{1}}选项。