使用最常用的类型类函数类型

Dan*_*ter 8 haskell

我正在尝试在Haskell中编写一个简单的遗传算法.我认为第一步应该是为"遗传"个体制作一个类型类,如下所示:

class Genetic a where
    fitness :: (Ord b) => a -> b
Run Code Online (Sandbox Code Playgroud)

这似乎是合理的,我-我并不想限制的健身功能,以一种类似FloatDouble和概念上都适应度函数应该做的是提供个人的排序.

但是,当我为String包装器实现这个类型类时:

data DNA = DNA String
instance Genetic DNA where
    fitness (DNA s) = length s
Run Code Online (Sandbox Code Playgroud)

我在GHC中看到以下错误:

Could not deduce (b ~ Int)
from the context (Ord b)
  bound by the type signature for fitness :: Ord b => DNA -> b
Run Code Online (Sandbox Code Playgroud)

这不是我应该如何定义类型类函数?我是否必须将函数限制为特定的具体类型,或者为类型类构造函数提供另一个类型变量?

lef*_*out 13

Luqui解释了问题所在:fitness需要能够提供调用者可能请求的任何 Ord实例,当你真正想要的是一些最适合该类型的特定实例时.

这是IMO关联类型同义词的一个非常好的应用程序:

{-# LANGUAGE TypeFamilies, FlexibleInstances, FlexibleContexts #-}

class (Ord (Fitness a)) => Genetic a where
  type Fitness a :: *
  fitness :: a -> Fitness a

data DNA = DNA String
instance Genetic DNA where
  type Fitness DNA = Int
  fitness (DNA s) = length s
Run Code Online (Sandbox Code Playgroud)

  • @DanielBuckmaster,是的,准备加入编译器建议的任何扩展.类型代码有时候就像...... (3认同)
  • 虽然如果编译器推荐`IncoherentInstances`,也许是时候重新考虑了. (3认同)