Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 数据实例中的上下文_Haskell_Type Constraints_Gadt - Fatal编程技术网

Haskell 数据实例中的上下文

Haskell 数据实例中的上下文,haskell,type-constraints,gadt,Haskell,Type Constraints,Gadt,我有一个数据类型,它只有在其参数可以排序的情况下才有意义,但是我似乎需要深入研究一些复杂的、可能有黑客攻击的东西,才能让它工作(主要是GADTs)。 我所做的(受约束的数据类型)是否被认为是糟糕的haskell实践,是否有办法解决这个问题 对于感兴趣的人,以下是相关代码: {-# LANGUAGE GADTs #-} {-# LANGUAGE InstanceSigs #-} import Data.List (sort) data OrdTriple a where OrdTripl

我有一个数据类型,它只有在其参数可以排序的情况下才有意义,但是我似乎需要深入研究一些复杂的、可能有黑客攻击的东西,才能让它工作(主要是GADTs)。 我所做的(受约束的数据类型)是否被认为是糟糕的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]
起初,我以为我只是在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’

您不能使用标准的
Functor
类来执行此操作,因为它的
fmap
必须在没有约束的情况下对所有数据类型都有效

你可以和另一个班一起工作。一个选项是使用“细粒度函子”类,它允许您为每对类型
ab
使用单独的实例。(可能这已经有了一些标准名称,但我不记得了)

或者,可以使用约束参数化
函子
类:

{-# LANGUAGE GADTs, KindSignatures, MultiParamTypeClasses, 
    ConstraintKinds, TypeFamilies, FlexibleInstances #-}
{-# OPTIONS -Wall #-}
module CFunctor where

import Data.List (sort)
import Data.Kind (Constraint)

data OrdTriple a where
    OrdTriple :: (Ord a) => a -> a -> a -> OrdTriple a

class CFunctor (f :: * -> *) where
   type C f a :: Constraint
   cmap :: (C f a, C f b) => (a -> b) -> f a -> f b

-- regular functors are also constrained ones, e.g.
instance CFunctor [] where
   type C [] a = a ~ a
   cmap = fmap

instance CFunctor OrdTriple where
   type C OrdTriple a = Ord a
   cmap f (OrdTriple n d x) = OrdTriple n' d' x'
      where [n', d', x'] = sort [f n, f d, f x]

Functor必须适用于所有类型,而不仅仅是受
Ord
约束的类型。即使在实例中,也无法进一步约束它。这就是为什么像平衡树这样的结构也不能是函子。你不能把它变成函子。通常的解决方法是简单地实现一个单独的“映射”函数,就像对
Data.Set
Data.map
所做的那样。您的IxFunctor是否与or相关(略有不同)?我不知道它们是否以某种我看不到的方式代表了类似的概念,或者它们是否完全不同。@Zoeyhewl似乎我弄错了术语:上面的一个不是索引函子
fija
,而是其他东西。我记不起它的真名了,但如果在什么地方找不到它,我会很惊讶。我将删去这些术语,以免引起混淆。谢谢。对于CFunctor,我得到的
不在范围内:类型构造函数或类“约束”
@zoeyHew将看到我的编辑,我添加了导入并对类进行了一些修改,因为我还意识到我们需要函数依赖项或类型族。我选择后者。
{-# LANGUAGE GADTs, KindSignatures, MultiParamTypeClasses, 
    ConstraintKinds, TypeFamilies, FlexibleInstances #-}
{-# OPTIONS -Wall #-}
module CFunctor where

import Data.List (sort)
import Data.Kind (Constraint)

data OrdTriple a where
    OrdTriple :: (Ord a) => a -> a -> a -> OrdTriple a

class CFunctor (f :: * -> *) where
   type C f a :: Constraint
   cmap :: (C f a, C f b) => (a -> b) -> f a -> f b

-- regular functors are also constrained ones, e.g.
instance CFunctor [] where
   type C [] a = a ~ a
   cmap = fmap

instance CFunctor OrdTriple where
   type C OrdTriple a = Ord a
   cmap f (OrdTriple n d x) = OrdTriple n' d' x'
      where [n', d', x'] = sort [f n, f d, f x]