gpt4 book ai didi

haskell - 类型变量的多态性?

转载 作者:行者123 更新时间:2023-12-02 16:19:01 24 4
gpt4 key购买 nike

标题可能不太恰当,请继续阅读。

我最初想要的是:我正在编写 2D 矢量数据

data Vect a = Vect a a deriving (Show)

并且想要编写一个适用于所有 Vect anorm::Vect a -> Double 函数,其中 a 是 Integral 的实例> 或 float

对于 Double,我可以这样写:

norm :: Vect Double -> Double
norm (Vect x y) = sqrt $ x^2 + y^2

但我希望这个函数也可以与 Vect Int 一起使用。我可以编写另一个函数,例如:

normFromInt :: (Integral a) => Vect a -> Double
normFromInt (Vect x y) = sqrt . fromIntegral $ x^2 + y^2

拥有两个函数似乎相当尴尬。实现这一目标的好方法是什么?

<小时/>

我尝试为此使用特殊类:

class Vectorlike a where
norm :: a -> Double

instance (Integral a) => Vectorlike (Vect a) where
norm (Vect x y) = sqrt . fromIntegral $ x^2 + y^2
-- |
-- >>> norm (Vect 3 4 :: Vect Int)
-- 5.0

instance Vectorlike (Vect Double) where
norm (Vect x y) = sqrt $ x^2 + y^2

但是这样,当使用 `norm (Vect 3.0 4.0::Vect Double) 时,我收到错误

Overlapping instances for Vectorlike (Vect Double)
|| print $ norm (Vect 3.0 4.0 :: Vect Double)
foo.hs|40 col 13 error| Overlapping instances for Vectorlike (Vect Double)
|| arising from a use of `norm'
|| Matching instances:
|| instance Integral a => Vectorlike (Vect a)
|| -- Defined at /home/yosh/foo.hs:26:10
|| instance Vectorlike (Vect Double)
|| -- Defined at /home/yosh/foo.hs:32:10

我的问题是如何定义 norm 以便它适用于整数和 float ,并且错误消息不是主要关心的问题(这对我来说很令人困惑,但我认为我可以使用它之后)。

最佳答案

您只需要使用realToFrac,它将任何Real r => r值转换为Fractional f => f值:

norm :: (Real r, Floating f) => Vect r -> f
norm (Vect x y) = sqrt . realToFrac $ x^2 + y^2

那么它也适用于更多类型,而不仅仅是 Double

至于错误消息,从技术上讲,这两个实例没有重叠,但绝对可以。有人可以定义一个 Integral Double 实例,然后导入您的代码。编译器突然无法决定使用哪个实例!

虽然这种精确情况不太可能发生,但类型系统确实允许某人为 Double 实例化 Integral,并且这肯定可能发生在其他类型类和数据类型上.

关于haskell - 类型变量的多态性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30180737/

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