考虑以下类型类定义的类型的对:默认值须在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
我不认为这是去工作,除非你想添加一个'Typeable'约束或者其他东西。你能举出一些你想要这个的具体例子吗? – dfeuer
'可键入'(或'数据')约束是一个可以接受的折衷方案,但我无法弄清楚如何做到这一点与事件... – fakedrake
这段代码是如此......怪异......我可以'在没有更多背景的情况下给出具体的建议,具体地说,你试图完成什么。你有用例吗? – dfeuer