gpt4 book ai didi

class - Haskell 自定义数学类型和类

转载 作者:行者123 更新时间:2023-12-04 13:49:24 24 4
gpt4 key购买 nike

有没有办法让类实例返回一个不是实例类型的值?一个例子是想要为两个向量的标量积返回一个 Double 类型的值:

--  data structure to contain a 3D point in space
data Point3D = Point3D !Double !Double !Double
deriving (Eq, Ord)

instance Num Point3D where
-- Multiplication, scalar == Dot product
Point3D x1 y1 z1 * Point3D x2 y2 z2 = x1*x2 + y1*y2 + z1*z2 :: Double

此外,有没有办法定义运算符在不同类型的函数之间如何工作?例如,我想定义 Point3D x y z + Double a = Point3D (x + a) (y + a) (z + a)

最佳答案

Num 中的数值运算typeclass 都定义为类型 :: Num n => n -> n -> n ,因此操作数和返回值必须具有相同的类型。没有办法改变现有的类型类,所以你的选择是定义新的运算符或隐藏现有的 Num类并将其完全替换为您自己的实现。

为了实现可以具有不同操作数类型的运算符,您将需要一些语言扩展。

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}

而不是 Num - 类包含 + , -* ,为不同的操作数定义不同的类型类更灵活,因为虽然 Point3D * Double有道理, Point3D + Double通常不会。让我们从 Mul 开始.
class Mul a b c | a b -> c where
(|*|) :: a -> b -> c

没有扩展,类型类只包含一个类型参数,但带有 MultiParamTypeClasses ,我们可以声明一个类型类,如 Mul用于组合类型 a , bc .参数后面的部分, | a b -> c是一个“功能依赖”,在这种情况下,类型 c依赖于 ab .这意味着如果我们有一个像 Mul Double Point3D Point3D 这样的实例函数依赖声明我们不能有任何其他实例 Mul Double Point3D c ,其中 c除了 Point3D 之外的其他东西,即乘法的返回类型始终由操作数的类型明确确定。

以下是我们如何为 Mul 实现实例:
instance Mul Double Double Double where
(|*|) = (*)

instance Mul Point3D Double Point3D where
Point3D x y z |*| a = Point3D (x*a) (y*a) (z*a)

instance Mul Double Point3D Point3D where
a |*| Point3D x y z = Point3D (x*a) (y*a) (z*a)

但是,这种灵活性并非没有警告,因为它会使编译器的类型推断更加困难。例如,你不能简单地写
p = Point3D 1 2 3 |*| 5

因为字面意思 5不一定是 Double 类型.它可以是任何 Num n => n ,而且完全有可能有人声明了像 Mul Point3D Int Int 这样的新实例。其行为完全不同。所以这意味着我们需要明确指定数字文字的类型。
p = Point3D 1 2 3 |*| (5 :: Double)

现在,如果我们不想定义新的操作数,而是希望覆盖默认值 Num来自 Prelude 的类(class),我们可以这样做
import Prelude hiding (Num(..))
import qualified Prelude as P

class Mul a b c | a b -> c where
(*) :: a -> b -> c

instance Mul Double Double Double where
(*) = (P.*)

instance Mul Point3D Double Point3D where
Point3D x y z * a = Point3D (x*a) (y*a) (z*a)

关于class - Haskell 自定义数学类型和类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9388052/

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