首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GADT和Functor类的问题

GADT和Functor类的问题
EN

Stack Overflow用户
提问于 2013-06-22 22:37:51
回答 1查看 254关注 0票数 3

我在Haskell中定义了自己的数据类型来表示单变量多项式。

代码语言:javascript
复制
data Polinomio a where
    Pol  :: (Num a) => a -> Integer -> Polinomio a -> Polinomio a
    Cons :: (Num a) => a -> Polinomio a

我在这里使用了GADT来约束a变量,使其属于Num Class。现在,我想为Functor类定义我自己的实例

代码语言:javascript
复制
instance Functor Polinomio where
    fmap f (Cons x) = Cons $ f x
    fmap f (Pol x g p) = Pol (f x) g (fmap f p)

它不能编译给我这样的原因:

代码语言:javascript
复制
Polinomio_GADT.hs:31:23:
Could not deduce (Num b) arising from a use of `Cons'
from the context (Num a)
  bound by a pattern with constructor
             Cons :: forall a. Num a => a -> Polinomio a,
           in an equation for `fmap'
  at Polinomio_GADT.hs:31:13-18
Possible fix:
  add (Num b) to the context of
    the data constructor `Cons'
    or the type signature for
         fmap :: (a -> b) -> Polinomio a -> Polinomio b
In the expression: Cons
In the expression: Cons $ f x
In an equation for `fmap': fmap f (Cons x) = Cons $ f x

Polinomio_GADT.hs:32:26:
Could not deduce (Num b) arising from a use of `Pol'
from the context (Num a)
  bound by a pattern with constructor
             Pol :: forall a.
                    Num a =>
                    a -> Integer -> Polinomio a -> Polinomio a,
           in an equation for `fmap'
  at Polinomio_GADT.hs:32:13-21
Possible fix:
  add (Num b) to the context of
    the data constructor `Pol'
    or the type signature for
         fmap :: (a -> b) -> Polinomio a -> Polinomio b
In the expression: Pol (f x) g (fmap f p)
In an equation for `fmap':
    fmap f (Pol x g p) = Pol (f x) g (fmap f p)
In the instance declaration for `Functor Polinomio'

因此,我尝试使用语言扩展InstanceSigs将此约束添加到fmap定义中:

代码语言:javascript
复制
instance Functor Polinomio where
    fmap :: (Num a,Num b) -> (a -> b) -> Polinomio a -> Polinomio b
    fmap f (Cons x) = Cons $ f x
    fmap f (Pol x g p) = Pol (f x) g (fmap f p)

它不能从编译器中获取以下代码:

代码语言:javascript
复制
Polinomio_GADT.hs:31:13:
Predicate `(Num a, Num b)' used as a type
In the type signature for `fmap':
  fmap :: (Num a, Num b) -> (a -> b) -> Polinomio a -> Polinomio b
In the instance declaration for `Functor Polinomio'

你知道怎么解决这个问题吗?

EN

回答 1

Stack Overflow用户

发布于 2013-06-23 00:07:47

您的数据类型为

代码语言:javascript
复制
data Polinomio a where
    Pol  :: (Num a) => a -> Integer -> Polinomio a -> Polinomio a
    Cons :: (Num a) => a -> Polinomio a

现在看一下您对Functor的定义

代码语言:javascript
复制
instance Functor Polinomio where
    fmap f (Cons x) = Cons $ f x
    fmap f (Pol x g p) = Pol (f x) g (fmap f p)

由于GADT的约束,ghc能够推断出x的约束Num a。但问题出在不受限制的函数f中,因为f :: a -> b, x :: Num a => a推断f xb类型。因此它不能将f x限制为Cons所要求的Num b => b

因此,正如Daniel所指出的,您不能向您的Functor类添加约束。您可以定义自己的受限函数器类,如here,也可以使用rmonad中的RFunctor。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17251891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档