隨着近期發佈的關於HaskellDB的文章,我一直有動力再次研究HList。因爲我們現在在GHC中有-XDataKinds
,它實際上有一個異類列表的例子,所以我想調查HList如何使用DataKinds。到目前爲止,我有以下幾點:是否可以刪除此DataKinds支持的異構列表實現的OverlappingInstances?
{-# 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
可正常工作,但我在這個項目的目標是嘗試做無類型類儘可能。所以這裏有兩個問題。首先,是否有可能編寫(=?)
(記錄字段存取器函數)而沒有類型類?如果不是,它可以寫在沒有重疊的情況下嗎?
我想我的第一個問題是不可能的,但也許第二個問題是可能的。我很想聽聽人們的想法!
由於原來的HList設法擺脫了只使用'MultiParamTypeClasses'和'FunctionalDependencies',我想可以加入(和使用)'DataKinds '不會改變這一點。 –
@Ptharien'sFlame HList文件使用overlappingInstances來實現TypeEq。其他一切都可以使用TypeEq –
@PhilipJF然後你需要的只是'TypeFamilies'和'MultiParamTypeClasses',不需要'TypeEq'! –