10

マルチパラメーター型シノニムのクラス インスタンスを定義することが可能かどうか (およびその方法) を把握しようとしています。

例えば:

{-# 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ですか?

4

2 に答える 2

15

書いてある通り無理です。型シノニムは、特に型クラス パラメーターとして使用するには、一般に完全に適用する必要があります。

型シノニムを十分に eta-reduce できる場合は、インスタンスが可能であることに注意してください。それが参照するタイプではなく、完全に適用する必要があるのはシノニムです。したがって、これは機能します:

type F = (->)

instance C F a b where
    doc f x = f x

型シノニムの展開に関する規則の一部を緩和するLiberalTypeSynonyms拡張機能がありますが、ここでは役に立ちません。部分的に適用された型シノニムを別の型シノニムの型パラメーターとして指定するようなことしかできません。それ以外の場合は、すべてを完全に拡張する必要があります。

この制限が必要な理由の 1 つを確認するには、次の型シノニムを検討してください。

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)ですか?

于 2013-04-17T12:37:37.580 に答える
3

型シノニムを定義できるようにするには、インスタンスに完全に適用する必要があります。予想されるように、の種類はFis ではなく、さらに 2 つの型引数が指定されるまで無効です。* -> * -> *試す

type F = (->)

代わりは。

于 2013-04-17T12:38:07.720 に答える