为什么这个表达模糊不清?

时间:2015-09-03 23:24:09

标签: haskell

在这里,我定义了两个类FOF用于多态函数fO用于多态值o

{-# LANGUAGE MultiParamTypeClasses #-}

class F a b where
    f :: a -> b

class O a where
    o :: a

data K = K 
data L = L 
data M = M 

instance O K where
    o = K 

instance O L where
    o = L 

instance F K L where
    f K = L 

instance F L K where
    f L = K 

instance F L L where
    f L = L 

instance F M K where
    f M = K 

为了方便起见,这里列出了任何一个类的可能实例:

F K L
F L K
F L L
F M K

O K
O L

现在,如果我在GHCi中输入以下内容:

f o :: K

我希望Haskell能够确定,因为最终结果必须是K,这意味着f的可能实例是F M KF L K,但是从{{ 1}}只能是o而不是L,必须是MoLf的情况。也就是说,没有任何其他可能性,结果应该是F L K。但事实证明,Haskell无法解决这个问题:

K

你认为这是因为编译器不够智能,或者你认为我的表达中存在实际的歧义吗?

1 个答案:

答案 0 :(得分:1)

o会返回任何类型:o :: a

将其提供给f会产生

:t f o
  f o :: F a b => b

这意味着a可以是任何类型。所以o含糊不清。

f o :: Kb Kf :: a -> b F a bf

上述两种情况都会产生instance F a0 K

的可能实例
instance F L K

instance K M K

有两个候选人

o

O返回instance O K instance O L 类的任何实例。只定义了两个实例:

f o :: K

因此o含糊不清,因为GHC含糊不清。

我认为Route::get('password/email', ['uses' => 'Auth\PasswordController@getEmail', 'as', 'session.getEmail']); 以这种方式推断类型(仅搜索合适的实例),以便不陷入循环。但我只是开始学习它,所以我在这里错了。

有一种描述herehere (shortly)的技术可以帮助编译器推断出正确的实例。