haskell - 多参数类型同义词实例

标签 haskell typeclass

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

例如:

{-# 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/

相关文章:

haskell - 缺乏类型推断导致编译失败,没有实例歧义

具有类型构造函数的类型类定义的 Haskell 实例

haskell - 是否有针对部分类型同义词实例的 Haskell (GHC) 扩展?

Haskell:如何将接口(interface)与实现分离

haskell - 如何在 Haskell 中使用代理? (可能使用更高等级的类型扩展)

haskell - 对类型类约束感到困惑

performance - 从集合中选择随机元素,比线性时间快(Haskell)

Haskell:类型类和实例(不在范围内:数据构造函数..)

c# - C# 接口(interface)和 Haskell 类型类之间的区别

haskell - 如何从Haskell链接到C#(即托管)DLL?