我有个关于类型类的问题。我有以下代码:
import Foreign.C.Types (CDouble, CFloat)
class Floating a => Trigonometry a where
versin :: a -> a
versin x = 1 - cos x
vercos :: a -> a
vercos x = 1 + cos x
coversin :: a -> a
coversin x = 1 - sin x
covercos :: a -> a
covercos x = 1 + sin x
haversin :: a -> a
haversin x = versin x * 0.5
havercos :: a -> a
havercos x = vercos x * 0.5
hacoversin :: a -> a
hacoversin x = coversin x * 0.5
hacovercos :: a -> a
hacovercos x = covercos x * 0.5
instance Trigonometry CDouble
instance Trigonometry CFloat
instance Trigonometry Double
instance Trigonometry Float现在我的问题是:可以有无限数量的Floating实例,很明显,每个Floating实例都可以是Trigonometry的一个实例,而不需要额外的实现。有没有办法避免底层的显式实例声明,并自动使所有Floating实例也成为Trigonometry实例?
干杯!
发布于 2022-01-26 11:06:31
在这种情况下,可能根本不需要定义类型类型,您可以使用Floating类型约束将这些函数实现为顶级函数:
versin :: Floating a => a -> a
versin x = 1 - cos x
vercos :: Floating a => a -> a
vercos x = 1 + cos x
coversin :: Floating a => a -> a
coversin x = 1 - sin x
covercos :: Floating a => a -> a
covercos x = 1 + sin x
haversin :: Floating a => a -> a
haversin x = versin x * 0.5
havercos :: Floating a => a -> a
havercos x = vercos x * 0.5
hacoversin :: Floating a => a -> a
hacoversin x = coversin x * 0.5
hacovercos :: Floating a => a -> a
hacovercos x = covercos x * 0.5如果您想为特定的Floating类型做一个特殊的实现,您确实可以使用一个类型类型,但是如果您实现了一个instance Floating a => Trigonometry a,那么您很可能最终会使用重叠实例。
发布于 2022-01-26 09:10:50
对于那些正在寻找类似东西的人,我想出了答案:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Algorithms.Math.Trigonometry where
class Floating a => Trigonometry a where
versin :: a -> a
versin x = 1 - cos x
vercos :: a -> a
vercos x = 1 + cos x
coversin :: a -> a
coversin x = 1 - sin x
covercos :: a -> a
covercos x = 1 + sin x
haversin :: a -> a
haversin x = versin x * 0.5
havercos :: a -> a
havercos x = vercos x * 0.5
hacoversin :: a -> a
hacoversin x = coversin x * 0.5
hacovercos :: a -> a
hacovercos x = covercos x * 0.5
instance Floating a => Trigonometry a语言扩展魔术:)
发布于 2022-01-27 13:32:51
您不希望Haskell推断其他类型是Trigonometry的实例--这会导致它在类型上使用功能的情况,因为它发现了一个似乎适用的类型类型。例如,您可能会故意在一个类型上省略一个Ord实例,因为对于该类型,Ord没有意义,因此可以很容易地推断它。
如果要将函数应用于任何合适的类型,只需删除类型。
https://stackoverflow.com/questions/70860896
复制相似问题