繁体   English   中英

Haskell:类型类可以定义类型(ala类型特征)

[英]Haskell: Can typeclasses define types (ala type traits)

是否可以将类型作为类型类的一部分? 就像是:

class KeyTraits v where
    keyType :: *
    key :: v -> keyType

data TableRow = { date :: Date, metaData :: String, value :: Int }

instance KeyTraits TableRow where
    keyType = Date
    key = date

这些“类型级”功能可以在其他地方使用吗? 例如:

-- automatically deduce the type for the key, from the value type, using
-- the typeclass
data MyMap v = { getMap :: (KeyTraits v) => Map (keyType) v }

我可能正在做一些完全错误的事情,但我基本上希望能够定义类似上面的类型关系(例如,某些值已经可能具有可用作Key的数据)。 如果那是不可能的,或者很难,你能否提出一个更具惯用性的更好的设计?

谢谢!

看一下类型系列

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}

class KeyTraits k where
    type KeyType k :: *
    key :: v -> KeyType k

data TableRow = TableRow { date :: Date, metaData :: String, value :: Int }

instance KeyTraits TableRow where
    type KeyType TableRow = Date
    key = date

data MyMap v = MyMap { getMap :: (KeyTraits v) => Map (KeyType v) v }

类型族正是您所寻找的,但还有另一种实现其功能的方法,即具有功能依赖性的 多参数类型类 使用这些扩展,您的代码可能如下所示:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

class KeyTraits v k | v -> k where
    key :: v -> k

data TableRow = { date :: Date, metaData :: String, value :: Int }

instance KeyTraits TableRow Date where
    key = date

这里,关联类型迁移到类型类参数,之前隐含的vk之间的关系现在变得明确,具有功能依赖性。

这完全等同于关联类型,但IMO提供了更清晰的语法,尤其是在使用类型类的函数中。 相比:

getMap :: (KeyTraits v) => Map (KeyType v) v

getMap :: (KeyTraits k v) => Map k v

当单个类型声明中出现更多类型和更多类型类时,这变得更加明显。

但是,类型族似乎是haskell社区的首选,事实上整个扩展比MPTC + FD更强大,因为类型族可以声明没有类型类,并且还有数据族。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM