1

GHC 抱怨此代码:

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, ScopedTypeVariables #-}

class Test a b where
    data Data a b
    data Marker a b
    test :: Marker a b -> Bool

work :: (Test a b, Test a2 b2) => Data a b -> Data a2 b2 
work =
    let (m :: Marker a2 b2) = undefined
    in if test m then undefined else undefined

随着消息:

You cannot bind scoped type variables `a2', `b2'
  in a pattern binding signature
In the pattern: m :: Marker a2 b2

我不想将函数的实际功能work移到Test类中,因为test谓词在多个函数中使用。

4

2 回答 2

2

如果将类型变量带入作用域,它就会编译:

work :: forall a b a2 b2. (Test a b, Test a2 b2) => Data a b -> Data a2 b2 
work =
    let (m :: Marker a2 b2) = undefined
    in if test m then undefined else undefined

没有显式forall,类型变量a2b2let-binding 是新的类型变量。

于 2013-01-06T18:29:10.010 回答
2

forall a b a2 b2.用作a2,b2 in将Marker a2 b2被视为新的。使用forall会将它们带入范围:

work :: forall a b a2 b2. (Test a b, Test a2 b2) => Data a b -> Data a2 b2 

有关forall 关键字的更多信息

于 2013-01-06T18:32:18.407 回答