gpt4 book ai didi

Haskell Typeclass 类型约束和推导

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

我一直在读《Learn You a Haskell》一书,并且正在尝试了解 Haskell 类型类。作为练习,我尝试创建一个简单的向量类型类。下面的代码片段让我有些悲伤(导致我在 StackOverflow 上发表了第一篇文章):

data Vec2 a = Vec2 (a,a) deriving (Show, Eq, Read)

class Vector a where
(<*) :: (Num b) => a -> b -> a

instance (Num a) => Vector (Vec2 a) where
Vec2 (x,y) <* a = Vec2 (a*x, a*y)

我收到以下错误消息:

Could not deduce (a~b) from the context (Num a) or from (Num b) bound by the type signature for
<* :: Num b => Vec2 a -> b -> Vec2 a

看起来类型类中指定的 Num 应该提供 a 的类型,并且实例中的 Num a 规范应该提供xy 的类型,那么它为什么会提示呢?我对这段代码有什么误解?

最佳答案

(*) :: Num a => a -> a -> a的类型。但是当你真正尝试使用 * 时,您实际上是将两个不相关的类型相乘 Num实例和编译器无法推断它们是相同的。

为了更清楚地解释它,请查看 <* 的类型以及 b 的通用量化

(<*) :: (Num b) => a -> b -> a

你在这里所说的是,给我任何具有 Num 的类型实例,我将能够将其与我的向量相乘,但你想说的是不同的东西。

你需要一些怎么说 a类型 Vec2 ab 相同类型 (<*) :: Num b => a -> b -> a ,只有这样你才能将它们相乘。这是使用类型族来确保此约束的解决方案。

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}

data Vec2 a = Vec2 (a,a) deriving (Show, Eq, Read)

class (Num (VectorOf a)) => Vector a where
type VectorOf a :: *
(<*) :: a -> (VectorOf a) -> a

instance (Num a) => Vector (Vec2 a) where
type VectorOf (Vec2 a) = a
Vec2 (x,y) <* a = Vec2 (a*x, a*y)

关于Haskell Typeclass 类型约束和推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18284798/

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