当前位置:  开发笔记 > 小程序 > 正文

如何仅为Floating创建实例?

如何解决《如何仅为Floating创建实例?》经验,为你挑选了1个好方法。

有一个类,我想为其定义一个实例.它看起来像这样:

data MyValue a = MyValue a

class TestClass a where
    funcOne:: (Real b) => a b -> a b
    funcTwo:: (Real b) => a b -> a b -> a b


instance TestClass MyValue where
    funcOne (MyValue x) = MyValue (x*pi)
    funcTwo (MyValue x) (MyValue y) = MyValue (x*y)

我收到以下错误:

Could not deduce (Floating b) arising from a use of `pi'
      from the context: Real b

我理解错误,但我不知道如何解决它.

我无法更改(Real b)to,(Floating b)因为其他实例也应该使用Integral类型.但仅有MyValue意义Floating.有可能告诉编译器,instance TestClass MyValue只能使用Floating

如果不是,那么如何将结果转换x*piRealx参数相同的?如果类型是例如Integral,会发生什么并不重要,因为MyValue在这种情况下没有意义



1> leftaroundab..:

您可以实现此目的,但您需要修改该数据类型或类.

如果MyValue使用Floating特别有意义,那么将该约束烘焙到其构造函数中可能是有意义的.

{-# LANGUAGE GADTs #-}

data MyValue :: * -> * where
  MyValue :: Floating a => a -> MyValue a

这保证任何功能接受MyValue aa实际上是一个Floating实例,因此

  funcOne (MyValue x) = MyValue $ x*pi

然后会工作.

如果这是一个共同的主题,需要对包含的类型进行特定约束,那么您可以(而不是总是要求Real)使约束依赖于实例:

{-# LANGUAGE TypeFamilies, ConstraintKinds #-}
import GHC.Exts (Constraint)

class TestClass a where
  type Testable a b :: Constraint
  type Testable a b = Real b  -- default constraint
  funcOne:: Testable b => a b -> a b
  funcTwo:: Testable b => a b -> a b -> a b

instance TestClass MyValue where
  type Testable MyValue b = Floating b
  funcOne (MyValue x) = MyValue $ x*pi
  ...

但是,如果您需要再次人为地约束参数,那么首先TestClass处理参数化(* -> *)类型可能不是正确的决定.为什么不简单地做

class TestClass q where
  funcOne :: q -> q
  funcTwo :: q -> q -> q

instance Floating a => TestClass (MyValue a) where
  funcOne (MyValue x) = MyValue $ x*pi
  funcTwo (MyValue x) (MyValue y) = MyValue $ x*y

无论如何,这对我来说似乎更干净.如果某些方法确实需要访问包含的类型,那么使用相关类型系列也可以使用此方法:

class TestClass q where
  type ToTest q :: *
  ...

instance Floating a => TestClass (MyValue a) where
  type ToTest (MyValue a) = a
  ...

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有