我试图弄清楚是否有可能(以及如何)为多参数类型同义词定义类实例。

例如:

{-# 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-reduce足够多,则可以使用一个实例。这是必须完全应用的同义词,而不是它所指的类型。因此,这将工作:

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/

10-11 15:24
查看更多