我最近遇到过一种情况,我希望能够在实例声明中组合类型构造函数。我本来希望这样做:
instance (SomeClass t, SomeClass t') => SomeClass (t . t') where
定义了(t . t')
,(t . t') a = t (t' a)
(t
和t'
有* -> *
种。我们可以部分应用类型构造函数,比如函数,那么什么是我们不能把它们组合起来的原因吗?另外,是否有一种解决方法可以解决我想要实现的目标?也许是在平等约束下?
(我知道Control.Compose存在,但它只是创建了一个newtype
包装器 - 我想要一个类型的同义词。)
答案 0 :(得分:10)
(我知道
onmessage = function(e) { postMessage(e.data); }
存在,但它只是创建了一个Control.Compose
包装器 - 我想要一个类型的同义词。)
Haskell中不允许这样做。必须完全应用类型同义词:您不能只编写newtype
,Compose t t'
。
允许部分应用的类型同义词会导致类型级别的lambdas,这使得类型推断不可判定,因此在Haskell中缺乏对它的支持。
例如,(启用所有相关的GHC扩展)
Compose t t' a
结果:
type Compose t t' a = t (t' a)
data Proxy (k :: * -> *) = Proxy
pr :: Proxy (Compose [] [])
pr = Proxy
类似地,
Type synonym ‘Compose’ should have 3 arguments, but has been given 2
In the type signature for ‘pr’: pr :: Proxy (Compose [] [])
的产率:
class C k where f :: k Int -> Int
instance C (Compose [] []) where f _ = 6
以下是允许使用类型同义词部分应用程序 的示例(启用Type synonym ‘Compose’ should have 3 arguments, but has been given 2
In the instance declaration for ‘C (Compose [] [])’
):
LiberalTypeSynonyms
但请注意,这仅仅是因为在同义词扩展后我们获得了完全应用的类型type T k = k Int
type S = T (Compose [] [])
bar :: S -> S
bar = map (map succ)
(即[] ([] Int)
)。粗略地说,这个功能不允许在没有它的情况下做任何事情,手动扩展同义词。