私は、その引数が順序付けられていれば意味をなさないデータ型を持っていますが、それを動作させるには複雑で潜在的にハッキリなものに深く関わる必要があるようです(主にGADT)。 私がやっていることは(制約付きのデータ型)悪いハズケルの習慣とみなされていますか?これを回避する方法はありますか?興味のある方のためデータインスタンス内のコンテキスト
は、ここに関連するコードです:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
import Data.List (sort)
data OrdTriple a where
OrdTriple :: (Ord a) => a -> a -> a -> OrdTriple a
instance Functor OrdTriple where
fmap :: (Ord a, Ord b) => (a -> b) -> OrdTriple a -> OrdTriple b
fmap f (OrdTriple n d x) = OrdTriple n' d' x'
where
[n', d', x'] = sort [f n, f d, f x]
が最初に私は、私はちょうどのFunctorインスタンスにコンテキストを入れしようと思いました(それは私が苦労してるだけインスタンスです)が、それは私らしいですできません(含まれている型の言及はありません)、私はまだfmap
の制約が必要と思いますが、戻り値の型は注文可能です。
No instance for (Ord a)
Possible fix:
add (Ord a) to the context of
the type signature for
fmap :: (a -> b) -> OrdTriple a -> OrdTriple b
When checking that:
forall a b.
(Ord a, Ord b) =>
(a -> b) -> OrdTriple a -> OrdTriple b
is more polymorphic than:
forall a b. (a -> b) -> OrdTriple a -> OrdTriple b
When checking that instance signature for ‘fmap’
is more general than its signature in the class
Instance sig: forall a b.
(Ord a, Ord b) =>
(a -> b) -> OrdTriple a -> OrdTriple b
Class sig: forall a b. (a -> b) -> OrdTriple a -> OrdTriple b
In the instance declaration for ‘Functor OrdTriple’
ファンクタは、すべてのタイプには適用されませんでなければならない:1は制約に
Functor
クラスをパラメータすることができ、またを(おそらくこれは、すでにいくつかの標準的な名前を持っているが、私は覚えていないことができます) 'Ord'によって制約されたものだけです。あなたのインスタンスでもそれをさらに制限することはできません。これは、バランスの取れた木のような構造物が、ファンクターのいずれにもなり得ない理由です。 – bheklilr
あなたはそれをファンクタにすることはできません。その周りの通常の方法は、単に 'Data.Set'と' Data.Map'で行われるように、別々の "マップ"関数を実装することです。 – Cubic