6

我在 haskell 中建立了一个几何库。我不打算发布它,它只是我用来提高我的语言知识的一个项目。

我有一个Local数据类型,具有以下定义

data Local a where
    MkLocal :: (Vectorise a) => ReferenceFrame -> a -> Local a

参考框架是指向框架原点的向量和表示框架旋转的角度,两者都定义为“绝对”参考框架(嘿,这不是现实世界!)。Vectorise几何是一种具有可逆变换为 的列表的几何Vector

我突然想到 Local 可能是以下实例Functor

instance Functor Local where
     fmap f geom = localise (frame geom) (f $ local geom)

但是编译器抱怨没有 Vectorisable 的实例用于定义中的 localize 。有没有办法使用无数 GHC 扩展之一来解决这个限制?

编辑:根据评论中的要求,这里是一些使用的类型

local :: Local a -> a
frame :: Local a -> ReferenceFrame
localise :: (Vectorise a) => ReferenceFrame -> a -> Local a

错误是

No instance for (Vectorise b)
  arising from a use of `localise'
In the expression:
  localise (frame geom) (f $ local geom)
In an equation for `fmap':
    fmap f lgeom = localise (frame geom) (f $ local geom))
In the instance declaration for `Functor Local'

这是有道理的,因为 for 的类型fmap(a -> b) -> f a -> f b. 它可以推断出它a必须是 的一个实例Vectorise,但我想知道它如何推断出它b,除非我可以指定(以某种方式)我可以告诉编译器f必须具有受限的返回类型,而无需定义另一个类型类,而已经有一个几乎已经符合要求(或者,如果有人可以帮助解释为什么以这种方式限制类会以某种方式破坏类型推断)。

附言。我还修正了我在定义中颠倒local和颠倒的错字framefmap

4

1 回答 1

13

问题是它localise要求它的第二个参数具有 type Vectorise a => a,但是当您将f(具有 type a -> b)应用到local( of type Vectorise a => a)的结果时,不能保证结果值的 type 是Vectorise. 您真正想要的是Functor仅适用于具有Vectorise约束的类型的类似物。

直到最近,还不能定义这样的类型类。这是一个众所周知的问题和原因Data.Set没有Functor或没有Monad实例。然而,随着最近的ConstraintKindsGHC 扩展,这种“受限函子”终于成为可能:

{-# LANGUAGE GADTs, ConstraintKinds, TypeFamilies #-}
module Test
       where

import GHC.Exts (Constraint)

data ReferenceFrame = ReferenceFrame

class Vectorise a where
  ignored :: a

data Local a where
    MkLocal :: ReferenceFrame -> a -> Local a

local :: Vectorise a => Local a -> a
local = undefined

frame :: Local a -> ReferenceFrame
frame = undefined

localise :: (Vectorise a) => ReferenceFrame -> a -> Local a
localise = undefined

class RFunctor f where
  type SubCats f a :: Constraint
  type SubCats f a = ()
  rfmap ::  (SubCats f a, SubCats f b) => (a -> b) -> f a -> f b

instance RFunctor Local where
  type SubCats Local a = Vectorise a
  rfmap f geom = localise (frame geom) (f $ local geom)

ConstraintKinds 您可以在此处此处阅读更多信息。

于 2013-04-04T12:53:32.060 回答