gpt4 book ai didi

haskell - 类型类和 GADT

转载 作者:行者123 更新时间:2023-12-03 14:53:59 27 4
gpt4 key购买 nike

我在 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'

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

附言。我还修正了一个我颠倒的错字 localframe fmap 的定义颠倒了

最佳答案

问题是 localise要求其第二个参数的类型为 Vectorise a => a , 但是当你申请 f (类型为 a -> b )到 local 的结果(类型为 Vectorise a => a ),不能保证结果值的类型是 Vectorise 的实例.你真正想要的是 Functor 的模拟。仅适用于具有 Vectorise 的类型约束。

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

{-# 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 的更多信息 herehere .

关于haskell - 类型类和 GADT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15809235/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com