繁体   English   中英

Haskell - 类型类扩展

[英]Haskell - typeclass extension

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

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实例?

干杯!

对于这种情况,可能根本不需要定义类型类,您可以将这些函数实现为具有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 ,你最终可能会得到重叠的实例

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

{-# 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

语言扩展魔法:)

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

如果您希望 function 应用于任何合适的类型,您只需删除类型类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM