我正在尝试在Haskell中编写一个简单的遗传算法。我认为第一步应该是为“遗传”个体制作一个类型类,如下:
class Genetic a where
fitness :: (Ord b) => a -> b
这对我来说似乎是合理的 - 我不一定要将健身功能限制为类似Float
或Double
的类型,概念上所有健身功能应该做的是提供个人的排序
但是,当我为String
包装器实现这个类型类时:
data DNA = DNA String
instance Genetic DNA where
fitness (DNA s) = length s
我在GHC中看到以下错误:
Could not deduce (b ~ Int)
from the context (Ord b)
bound by the type signature for fitness :: Ord b => DNA -> b
这不是我应该如何定义类型类函数吗?我是否必须将函数限制为特定的具体类型,或者为类型类构造函数提供另一个类型变量?
答案 0 :(得分: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