GADT具有多态功能

时间:2015-10-04 14:36:20

标签: haskell gadt

我有一个函数的问题,我想使其非常多态。 我想通过分析或数字方式集成函数。当分析地进行积分时,我提供结果。 在数字的情况下,我想使用各种方法,目前来自tanhsinh的tanhsinh例程。 我还想了解有关小工具的更多信息,因此我尝试使用它们找到解决方案。

到目前为止,我有以下内容:

import qualified Data.VectorSpace as DV
import Numeric.Integration.TanhSinh

data IntegrationType a b  where
      MkAnalytic :: (DV.AdditiveGroup b) =>  (c -> b) -> c -> c -> IntegrationType Analytic b
      MkNumeric ::  NumericType  -> IntegrationType  Numeric [Result]

data Analytic = Analytic
data Numeric = Numeric
data Method = Trapez | Simpson
data IntBounds = Closed | NegInfPosInf | ZeroInf

data NumericType = MkSingleCoreTanhSinh  IntBounds Method  (Double -> Double)  Double Double
              | MkParallelTanhSinhExplicit IntBounds (Strategy [Double])  Method  (Double -> Double)  Double  Double
              | MkParallelTanhSinh IntBounds  Method  (Double -> Double)  Double  Double 

integrate :: IntegrationType a b -> b
integrate (MkAnalytic f l h) = f h DV.^-^ f l
integrate (MkNumeric (MkSingleCoreTanhSinh Closed Trapez f l h )) =  trap f l h
integrate (MkNumeric (MkSingleCoreTanhSinh Closed Simpson f l h )) =  simpson f l h

此代码编译,因为我在构造函数MkNumeric中明确声明类型变量b是

[Result]

为什么我必须这样做?我可以不在

中留下类型变量b
data IntegrationType a b  where
     MkNumeric ::  NumericType  -> IntegrationType  Numeric b

当我这样做时,我收到一个错误:

Could not deduce (b ~ [Result])
from the context (a ~ Numeric)
  bound by a pattern with constructor
             MkNumeric :: forall b. NumericType -> IntegrationType Numeric b,
           in an equation for `integrate'
  at test-classes-new-programm.hs:139:12-64
  `b' is a rigid type variable bound by
      the type signature for integrate :: IntegrationType a b -> b
      at test-classes-new-programm.hs:137:14
Relevant bindings include
  integrate :: IntegrationType a b -> b
    (bound at test-classes-new-programm.hs:138:1)
In the expression: trap f l h
In an equation for `integrate':
    integrate (MkNumeric (MkSingleCoreTanhSinh Closed Trapez f l h))
      = trap f l h

1 个答案:

答案 0 :(得分:3)

类型

integrate :: IntegrationType a b -> b

说,对于我选择的任何 ab,如果我使用integrate类型的值调用IntegrationType a b,我将返回b类型的值。定义时

MkNumeric ::  NumericType -> IntegrationType Numeric b

你让那些应用构造函数的人决定b是什么。所以我可以使用MkNumeric来制作一个值,例如,键入IntegrationType Numeric Int。但是,integrate知道如何制作[Result],而不是Int

工作代码中,只要integrate"打开证据框"通过匹配MkNumeric,它会学习b ~ [Result],因此它可以返回该类型的内容。