Haskell 多态性和类型类实例

Posted

技术标签:

【中文标题】Haskell 多态性和类型类实例【英文标题】:Haskell polymorphism and typeclass instance 【发布时间】:2017-01-14 03:14:07 【问题描述】:

我正在尝试用 Haskell 编写一个机器学习库,以提高我的 Haskell 技能。 我想到了一个涉及这样一个类的通用设计:

  class Classifier classifier where
    train :: X -> y -> trainingData
    classify :: trainingData -> x -> y

例如,给定一组示例 X,以及它们的真实标签 y,训练返回 在分类函数中使用的 trainingData。

所以,如果我想实现 KNN,我会这样做:

data KNN = KNN Int (Int -> Int -> Float) 

第一个 int 是邻居的数量,函数是计算向量之间距离的度量

  instance Classifier KNN where
---This is where I am stuck---

如何实现 Classifier 类型的类函数,以便它们是通用的 我将创建的所有分类器? 我觉得我把 Haskell 当作当务之急了 OOP 喜欢语言,我想用 Haskell 的方式来做。

【问题讨论】:

听起来您从错误的角度开始解决问题。您能否为您计划创建的各种分类器发布一些实际的classifytrain 函数的类型签名?那么是否、为什么以及如何抽象事物可能会很明显 【参考方案1】:

我会说您需要多参数类型类(具有可选的功能依赖项或类型族;我省略了这些)。

 class Classifier c s l  k where
      train :: c -> [(s, l)] -> k
      classify :: c -> k -> s -> l
      combine :: c -> k -> k -> k

分类器、样本、标签和知识类型之间存在四方面的关系。

train 方法从一组样本 (s) — 标签 (l) 对中推导出一些知识 (k)。分类方法使用该知识来推断样本的标签。 (combine 方法将两个知识连接在一起;不知道它是否总是适用)。

【讨论】:

【参考方案2】:

假设您的类型类不知道分类器提供什么,您可以执行类似的操作

class Classifier c where
  train :: [x] -> [y] -> c -> [(x,y)]
  classify :: [(x,y)] -> c -> x > y

这里,train 正在获取 x 类型的样本列表、y 类型的标签列表和某种类型的分类器 c,并且需要返回样本/标签列表对。

classify 获取样本/标签对列表(例如由train 生成的)、分类器和样本,并生成新标签。

(不过,至少我可能会将[(x,y)] 替换为Map x y 之类的东西。)

关键是分类器本身需要被trainclassify 使用,尽管你不需要知道此时会是什么样子。

KNN 的实例可能看起来像

instance Classifier KNN where

  train samples labels (KNN n f) = ...
  classify td (KNN n f) sample = ...

在这里,nf 可用于创建训练数据,并帮助选择训练数据中最近的成员作为样本点。

【讨论】:

一个可以处理各种类型的样本和标签的分类器可能过于通用而无用。 是的,我怀疑一个类型族(或具有功能依赖关系的多参数类型类)来约束可以与给定分类器一起使用的样本和标签类型会更好,但我不知道域足以提供建议。这至少适用于定义的KNN

以上是关于Haskell 多态性和类型类实例的主要内容,如果未能解决你的问题,请参考以下文章

Haskell 即席多态性

实例声明中的“非法多态或限定类型”(System-F 样式树)

在 Haskell 中存储多态回调

为什么有些Haskell函数不抽象具体的整数类型?

多态实例

C++多态模板类,模板类型对象的实例化