我有一个数据类型,只有在它的参数可以排序时才有意义,但是我似乎需要深入研究一些复杂并且可能有害的东西才能使其工作(主要是GADT)。 是我在做什么(受限数据类型)认为不好的haskell练习,有没有解决这个问题的方法?数据实例中的上下文
对于那些有兴趣,这里的相关代码:
{-# 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]
起初,我以为我只是把上下文的函子实例(这是我与挣扎的唯一实例),但似乎我不能(没有提及包含的类型),即使我可以仍然需要约束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’
函子必须适用于所有类型的,不只有那些受'Ord'限制的。即使在你的实例中,你也不能进一步限制它。这就是为什么像平衡树木这样的结构也不能成为仿函数的原因。 – bheklilr
你不能让它成为函子。通常的解决方法就是简单地实现一个单独的“map”函数,就像Data.Set和Data.Map一样。 – Cubic