2016-03-21 63 views
0

考虑以下类型类定义的类型的对:默认值须在Haskell存在约束

class Constraint a b where 
    g :: a -> b 

对于约束所有的情况下,我们可以推导出一组类型a,基本上是一个隐含的类型类,姑且称之为A。对于类型类别A的每个实例,存在另一个隐式类型B,其包括Constraint A b的所有可能类型b

所以这里是一段代码。

{-# LANGUAGE ExistentialQuantification #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
import Debug.Trace 

-- Contraining class 
class (Show a, Show b) => QandA a b where 
    g :: a -> b 

-- Some data types 
data A = A1 | A2 deriving (Show, Eq) 
data B = B1 | B2 deriving (Show, Eq) 
data C = C1 | C2 deriving (Show, Eq) 

instance QandA A B where 
    g A1 = B1 
    g A2 = B2 

instance QandA A C where 
    g A1 = C1 
    g A2 = C2 

-- We want to define a set of types that includes all the types that 
-- have Constraint a b given a. This can be done via an intermediate 
-- type. 
data DefaultAnswer q = forall a . (DefaultingQuestion q, QandA q a) => DefaultAnswer {answer :: a}; 

-- Polymorphism 
class DefaultingQuestion q where 
    def :: DefaultAnswer q 

instance DefaultingQuestion A where 
    def = DefaultAnswer C1 

其中typechecks但在ghci中

> (def :: DefaultAnswer A) 
(def :: DefaultAnswer A) :: DefaultAnswer A 

> answer (def :: DefaultAnswer A) 
<interactive>:574:1: 
    Cannot use record selector "answer" as a function due to escaped type variables 
    Probable fix: use pattern-matching syntax instead 
    In the expression: answer (def :: DefaultAnswer A) 
    In an equation for "it": it = answer (def :: DefaultAnswer A) 

现在我明白那就是,因为我用生存类型,GHC并没有真正寻找的类型的方式的answer,它只是确保可以有一个,即使它没有办法确定它是哪一个。那么当我真的想运行answer时,它无法弄清楚如何处理它。

所以我的问题是:有没有办法来定义默认的答案实现DefaultingQuestion

+3

我不认为这是去工作,除非你想添加一个'Typeable'约束或者其他东西。你能举出一些你想要这个的具体例子吗? – dfeuer

+0

'可键入'(或'数据')约束是一个可以接受的折衷方案,但我无法弄清楚如何做到这一点与事件... – fakedrake

+2

这段代码是如此......怪异......我可以'在没有更多背景的情况下给出具体的建议,具体地说,你试图完成什么。你有用例吗? – dfeuer

回答

1

为什么不每种类型:

import Data.Proxy 

class DefaultingQuestion q a where 
    def :: Proxy q -> a 

instance DefaultingQuestion A where 
    def _ = C1 
+0

是的代理正是我寻找的东西 – fakedrake