Con publicaciones recientes sobre HaskellDB, me he sentido motivado a buscar en HList nuevamente. Como ahora tenemos -XDataKinds
en GHC, que en realidad tiene un ejemplo de listas heterogéneas, quería investigar cómo se ven los HLists con DataKinds. Hasta el momento, tengo el siguiente:¿Es posible eliminar OverlappingInstances para esta implementación de lista heterogénea respaldada por 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
Esto funciona como se esperaba, pero mi objetivo en este proyecto fue tratar de hacerlo sin clases de tipos tanto como sea posible. Entonces hay 2 preguntas aquí. En primer lugar, ¿es posible escribir (=?)
(la función de acceso al campo de registro) sin una clase de tipo? Si no, ¿puede escribirse sin superponer instancias?
Imagino que no es posible para mi primera pregunta, pero quizás la segunda sea posible. Me encantaría escuchar lo que la gente piensa
Como el papel HList original logró salirse con la suya con solo usar 'MultiParamTypeClasses' y' FunctionalDependencies', me imagino que simplemente agregué (y usé) 'DataKinds 'no cambiaría eso. –
@ Ptharien'sFlame the HList paper usa las fuentes superpuestas para implementar TypeEq. Todo lo demás se puede hacer usando TypeEq –
@PhilipJF ¡Entonces todo lo que necesitas es 'TypeFamilies' y' MultiParamTypeClasses', no se requiere 'TypeEq'! –