Haskell 多参数类(模板化类型类)

bla*_*ers 4 haskell

我想为标量和向量实现一个通用的高斯函数。在 Ada 或 C++ 中,我只是为此选择模板,但在 Haskell 中它有点令人困惑。

我首先定义一个可以应用高斯算子的类,比如组合或计算概率:

class Gaussian g where
  (!*) :: g -> g -> g
  prob :: g -> a -> Float -- Here, I want a to be depending on g

data Gaussian1D = Gaussian1D Float Float
data Gaussian2D = Gaussian2D (Linear.V2 Float) Linear.V2(LinearV2 Float)
Run Code Online (Sandbox Code Playgroud)

,我想有类似的东西:

instance Gaussian Gaussian1D where
  prob :: Gaussian1D -> Float -> Float

instance Gaussian Gaussian2D where
  prob :: Gaussian2D -> Linear.V2 Float -> Float
Run Code Online (Sandbox Code Playgroud)

但我无法以一种很好的方式实现这一点。在不深入研究模板-haskell 领域的情况下,这是否可以通过多参数类实现,例如:

class Gaussian g a where
  (!*) :: g a -> g a -> g a
  prob :: g a -> a -> Float
Run Code Online (Sandbox Code Playgroud)

? 目前,当我执行以下操作时,我没有意识到这种情况:

data Gaussian1D = Gaussian1D Float Float

instance Gaussian Gaussian1D Float where
Run Code Online (Sandbox Code Playgroud)

有错误:( Expected kind ‘* -> *’, but ‘Gaussian1D’ has kind ‘*’顺便说一句,我不明白为什么会发生这个错误)

谢谢

Apl*_*123 5

这似乎是Functional dependencies的教科书用例,这是一种仅限 GHC 的语言功能,它允许多参数类型类,其中一个参数唯一地确定另一个:

{-# LANGUAGE FunctionalDependencies #-}

class Guassian g a | g -> a where
  (!*) :: g -> g -> g
  prob :: g -> a -> Float

instance Gaussian Gaussian1D Float where
  -- ...
Run Code Online (Sandbox Code Playgroud)