Ostatnie posty o HaskellDB, byłem zmotywowany do ponownego spojrzenia na HList. Ponieważ mamy teraz -XDataKinds
w GHC, który faktycznie ma przykład heterogenicznych list, chciałem zbadać, jak wyglądają HLists z DataKinds. Do tej pory mam następujące:Czy można usunąć OverlappingInstances dla tej implementacji listy heterogenicznych list zabezpieczonych 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
To działa zgodnie z oczekiwaniami, ale moim celem tego projektu było, aby spróbować zrobić to bez klas typu jak najwięcej. Oto 2 pytania tutaj. Po pierwsze, czy można napisać (=?)
(funkcja dostępu do rekordu pola) bez klasy typu? Jeśli nie, czy można go napisać bez nakładających się instancji?
Wyobrażam sobie, że nie jest możliwe moje pierwsze pytanie, ale może drugie może być możliwe. Chciałbym usłyszeć, co ludzie myślą!
Ponieważ oryginalny dokument HList zdołał uciec tylko przy użyciu 'MultiParamTypeClasses' i' FunctionalDependencies', wyobrażałbym sobie tylko dodawanie (i używanie) 'DataKinds 'nie zmieni tego. –
@ Ptharien'sFlame w dokumencie HList używa nakładających się instancji do wdrożenia TypeEq. Cała reszta może zostać wykonana przy użyciu TypeEq –
@PhilipJF. Wszystko, czego potrzebujesz, to 'TypeFamilies' i' MultiParamTypeClasses', bez 'TypeEq' wymagany! –