7

私はいくつかの不自然なタイプを持っています:

{-# LANGUAGE DeriveFunctor #-}

data T a = T a deriving (Functor)

...そしてその型は、何らかの工夫されたクラスのインスタンスです:

class C t where
    toInt :: t -> Int

instance C (T a) where
    toInt _ = 0

T aすべてのクラスのインスタンスである関数制約でどのように表現できますaか?

たとえば、次の関数を考えてみましょう。

f t = toInt $ fmap Left t

直感的にはfor allでtoInt動作するので上記の関数が動作することを期待しますが、それを型で表現することはできません。これは動作しません:T aa

f :: (Functor t, C (t a)) => t a -> Int

...適用fmapすると型が になったからEither a bです。次を使用してこれを修正することはできません:

f :: (Functor t, C (t (Either a b))) => t a -> Int

...bは、普遍的に量化された変数を表していないためです。次のようにも言えません。

f :: (Functor t, C (t x)) => t a -> Int

... またはforall x、制約がすべてに対して有効であることを示唆するために使用しますx

したがって、私の質問は、制約がその型変数の一部に対してポリモーフィックであると言う方法があるかどうかです。

4

1 に答える 1

7

制約パッケージの使用:

{-# LANGUAGE FlexibleContexts, ConstraintKinds, DeriveFunctor, TypeOperators #-}

import Data.Constraint
import Data.Constraint.Forall

data T a = T a deriving (Functor)

class C t where
    toInt :: t -> Int

instance C (T a) where
    toInt _ = 0

f :: ForallF C T => T a -> Int
f t = (toInt $ fmap Left t) \\ (instF :: ForallF C T :- C (T (Either a b)))
于 2012-10-04T00:06:35.853 に答える