选择不明确类型下的默认实例

时间:2016-05-03 18:36:04

标签: haskell

是否有类型类方法的Haskell语言扩展名为"使用唯一可用的潜在实例"?

我想编译以下内容

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances     #-}

class Foo a r where
 foo :: a -> r 


instance Foo a (Bool -> a) where
  foo x _ = x 

-- This compiles 
-- bar :: Int -> Bool

-- This does not  
bar :: a -> Bool  
bar _ = True 


use :: Bool 
use = bar $ foo _5 True
  where
    _5 :: Int 
    _5 = 5 

现在我收到以下错误:

     No instance for (Foo Int (Bool -> r0))
  (maybe you haven't applied enough arguments to a function?)
  arising from a use of ‘foo’
The type variable ‘r0’ is ambiguous
Note: there is a potential instance available:
  instance Foo a (Bool -> a) -- Defined at tests/pos/Fixme.hs:9:10

但由于只有一个潜在的实例可用,是否有办法强制ghc使用该实例?或者有一种方法可以在类型不明确时将某个实例声明为默认实例吗?

1 个答案:

答案 0 :(得分:3)

标准技巧是让你的实例更具多态性,因此:

instance (a ~ b, bool ~ Bool) => Foo a (bool -> b) where
    foo x _ = x

这使您无法编写其他函数实例,但会明确在需要函数实例时要使用的类型。您需要启用TypeFamilies扩展程序才能执行此操作。在您的特定情况下,您可能只能使用instance a ~ b => Foo a (Bool -> b),这将允许使用其他参数类型的更多函数实例,但代价是更频繁的模糊错误。

有关此技巧的更多解释,请参阅a previous answer of mine