我试图弄清楚是否可以(以及如何)为多参数类型同义词定义类实例。
例如:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
type F a b = a -> b
data DF a b = DF (a -> b)
class C c a b where
doc :: c a b -> a -> b
它适用于多参数类型实例:
instance C DF a b where
doc (DF f) x = f x
但它不适用于类型同义词:
-- ERROR:
--
-- Type synonym `F' should have 2 arguments, but has been given none
-- In the instance declaration for `C F a b'
--
instance C F a b where
doc f x = f x
是否可以为F
定义一个类型类实例?
最佳答案
这是不可能的。一般来说,类型同义词必须完全应用才能使用它们,尤其是 as a type class parameter .
请注意,如果您可以对类型同义词进行足够的 eta 缩减,则实例是可能的;必须完全应用的是同义词,而不是它所引用的类型。所以这会起作用:
type F = (->)
instance C F a b where
doc f x = f x
有a LiberalTypeSynonyms
extension that relaxes some of the rules关于扩展类型同义词,但它在这里没有帮助——它只能让你做一些事情,比如将部分应用的类型同义词作为另一个类型同义词的类型参数。一切都必须完全扩展才能使用。
要了解此限制必要的原因之一,请考虑以下类型同义词:
type Flip f a b = f b a
以及以下实例:
instance Functor (Flip Either a) where
fmap _ (Right x) = Right x
fmap f (Left x) = Left (f x)
回想一下,还有一个实例 Functor (Either a)
它做同样的事情,除了镜像。两者都很明智Functor
实例。
请记住,与 newtype
不同,类型同义词被认为与它们引用的类型相同,表达式 fmap not (Right True :: Either Bool Bool)
的值应该是多少?是?
关于haskell - 多参数类型同义词实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16059948/