gpt4 book ai didi

具有上下文的 Haskell 数据类型

转载 作者:行者123 更新时间:2023-12-02 18:30:14 24 4
gpt4 key购买 nike

我想为 Vertex 编写基本实现。

data Point a = Point a a

class XY c where

x :: c a -> a

y :: c a -> a

class XY c => Vertex c where

translate :: c a -> c a -> c a

scale :: a -> c a -> c a

rotate :: a -> c a -> c a

instance XY Point where

x (Point first second) = first

y (Point first second) = second

instance Vertex Point where

translate xy1 xy2 = Point (x xy1 + x xy2) (y xy1 + y xy2)

scale a xy = Point ((*a) $ x xy) ((*a) $ y xy)

rotate a xy = Point (x * cosA - y * sinA) (x * sinA + y * cosA) where
cosA = cos a
sinA = sin a

我必须创建 Vertex 类型类的实例,并在 Point 类型参数中实现 Floating 类型类。如果我像 instance (Floating a) => Vertex Point a where 那样实现它,我得到:

 Expected kind ‘* -> Constraint’,
but ‘Vertex Point’ has kind ‘Constraint’

用 Haskell 编写它的正确方法是什么?

最佳答案

哇哦。这个众所周知的问题是我最讨厌的问题。正确的解决方案是使 XYPoint用于参数类型。标量参数成为关联的类型同义词,一切都很容易进行:

{-# LANGUAGE TypeFamilies #-}

class XY p where
type Component p :: *
x :: p -> Component p
y :: p -> Component p

class XY p => Vertex p where
translate :: p -> p -> p
scale :: Component p -> p -> p
rotate :: Component p -> p -> p

N.B. In fact you could even consider simplifying this to always use the same component type, since you'll likely never need anything else:

class XY p where
x :: p -> Double
y :: p -> Double
class XY p => Vertex p where
translate :: p -> p -> p
scale :: Double -> p -> p
rotate :: Double -> p -> p

通过非参数形式,您现在可以轻松地在需要的地方添加数字类型约束,即在 instance Vertex Point 实例中:

instance XY (Point a) where
type Component (Point a) = a
x (Point xc _) = xc
y (Point _ yc) = yc

instance Floating a => Vertex (Point a) where
translate xy1 xy2 = Point (x xy1 + x xy2) (y xy1 + y xy2)
scale a xy = Point ((*a) $ x xy) ((*a) $ y xy)
rotate a xy = Point (x * cosA - y * sinA) (x * sinA + y * cosA)
where cosA = cos a
sinA = sin a

出于某种原因,大多数人更喜欢为几何实体创建参数化类而不是标量类型,这不仅完全没有必要,而且非几何,因为正确的几何形状显然依赖于实际的基础分解。

<小时/> 实际上我相当确定原因是什么:Edward Kmett 决定在 the linear library 中使用参数化类型。他应该更清楚,尤其是自从 Conal Elliott 的 vector-space library ,它以正确的方式做到这一点,已经存在了更长时间。

关于具有上下文的 Haskell 数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55010612/

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