随着最近有关 HaskellDB 的帖子,我有动力再次研究 HList。正如我们现在-XDataKinds
在 GHC 中所拥有的,它实际上有一个异构列表的示例,我想研究 HList 与 DataKinds 的外观。到目前为止,我有以下内容:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
import Data.Tagged
data Record :: [*] -> * where
RNil :: Record '[]
(:*:) :: Tagged f (FieldV f) -> Record t -> Record (f ': t)
type family FieldV a :: *
emptyRecord = RNil
(=:) :: (v ~ FieldV f) => f -> v -> Tagged f v
f =: v = Tagged v
class HasField x xs where
(=?) :: Record xs -> x -> FieldV x
instance HasField x (x ': xs) where
(Tagged v :*: _) =? _ = v
instance HasField x xs => HasField x (a ': xs) where
(_ :*: r) =? f = r =? f
--------------------------------------------------------------------------------
data EmployeeName = EmployeeName
type instance FieldV EmployeeName = String
data EmployeeID = EmployeeID
type instance FieldV EmployeeID = Int
employee = (EmployeeName =: "James")
:*: ((EmployeeID =: 5) :*: RNil)
employeeName = employee =? EmployeeName
employeeId = employee =? EmployeeID
这按预期工作,但我在这个项目中的目标是尝试尽可能不使用类型类。所以这里有2个问题。首先,是否可以在(=?)
没有类型类的情况下编写(记录字段访问器函数)?如果不是,是否可以在没有重叠实例的情况下编写它?
我想我的第一个问题是不可能的,但也许第二个问题是可能的。我很想听听人们的想法!