Ale*_*kiy 11 haskell typeclass
是否可以将类型作为类型类的一部分?就像是:
class KeyTraits v where
keyType :: *
key :: v -> keyType
data TableRow = { date :: Date, metaData :: String, value :: Int }
instance KeyTraits TableRow where
keyType = Date
key = date
Run Code Online (Sandbox Code Playgroud)
这些"类型级"功能可以在其他地方使用吗?例如:
-- automatically deduce the type for the key, from the value type, using
-- the typeclass
data MyMap v = { getMap :: (KeyTraits v) => Map (keyType) v }
Run Code Online (Sandbox Code Playgroud)
我可能正在做一些完全错误的事情,但我基本上希望能够定义类似上面的类型关系(例如,某些值已经可能具有可用作Key的数据).如果那是不可能的,或者很难,你能否提出一个更具惯用性的更好的设计?
谢谢!
小智 26
看一下类型系列.
{-# 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 }
Run Code Online (Sandbox Code Playgroud)
Vla*_*eev 11
类型族正是您所寻找的,但还有另一种实现其功能的方法,即具有功能依赖性的多参数类型类.使用这些扩展,您的代码可能如下所示:
{-# 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
Run Code Online (Sandbox Code Playgroud)
这里相关类型迁移到键入类参数,和之间的关系v和k,先前隐式的,现在变得明确的功能性依赖.
这完全等同于关联类型,但IMO提供了更清晰的语法,尤其是在使用类型类的函数中.相比:
getMap :: (KeyTraits v) => Map (KeyType v) v
Run Code Online (Sandbox Code Playgroud)
和
getMap :: (KeyTraits k v) => Map k v
Run Code Online (Sandbox Code Playgroud)
当单个类型声明中出现更多类型和更多类型类时,这变得更加明显.
但是,类型族似乎是haskell社区的首选,事实上整个扩展比MPTC + FD更强大,因为类型族可以声明没有类型类,并且还有数据族.
| 归档时间: |
|
| 查看次数: |
631 次 |
| 最近记录: |