首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell -类型扩展

Haskell -类型扩展
EN

Stack Overflow用户
提问于 2022-01-26 09:05:55
回答 3查看 103关注 0票数 2

我有个关于类型类的问题。我有以下代码:

代码语言:javascript
复制
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实例?

干杯!

EN

回答 3

Stack Overflow用户

发布于 2022-01-26 11:06:31

在这种情况下,可能根本不需要定义类型类型,您可以使用Floating类型约束将这些函数实现为顶级函数:

代码语言:javascript
复制
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,那么您很可能最终会使用重叠实例

票数 6
EN

Stack Overflow用户

发布于 2022-01-26 09:10:50

对于那些正在寻找类似东西的人,我想出了答案:

代码语言:javascript
复制
{-# 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

语言扩展魔术:)

票数 2
EN

Stack Overflow用户

发布于 2022-01-27 13:32:51

您不希望Haskell推断其他类型是Trigonometry的实例--这会导致它在类型上使用功能的情况,因为它发现了一个似乎适用的类型类型。例如,您可能会故意在一个类型上省略一个Ord实例,因为对于该类型,Ord没有意义,因此可以很容易地推断它。

如果要将函数应用于任何合适的类型,只需删除类型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70860896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档