我該如何實現這個toDSum
函數?我已經設法得到基本情況進行編譯,但我不知道如何通過遞歸調用來承載所有類型信息。在嘗試遞歸之前,我是否必須從類型中去掉Code
?如何編寫函數將泛型類型轉換爲與DSum一起使用的標記形狀類型?
(這是一個後續到How can I write this GEq instance?)
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Foo where
import Data.Dependent.Sum
import Data.GADT.Compare
import Data.Proxy
import Generics.SOP
import qualified GHC.Generics as GHC
type GTag t = GTag_ (Code t)
newtype GTag_ t (as :: [*]) = GTag (NS ((:~:) as) t)
instance GEq (GTag_ t) where
geq (GTag (Z Refl)) (GTag (Z Refl)) = Just Refl
geq (GTag (S x)) (GTag (S y)) = GTag x `geq` GTag y
geq _ _ = Nothing
toDSum :: forall t . Generic t => t -> DSum (GTag t) (NP I)
toDSum = foo . unSOP . from
where
foo ::()
=> NS (NP I) (Code t)
-> DSum (GTag t) (NP I)
foo = bar (Proxy :: Proxy t)
bar :: forall t1 .()
=> Proxy t1 -> NS (NP I) (Code t1)
-> DSum (GTag t1) (NP I)
bar _ (Z x) = GTag (Z Refl) :=> x
bar _ (S x) = undefined
你可能會更好過避免'Code'只要有可能。在上下文中,它是一個代碼,還是可以讓它完全呈多態? – dfeuer
我認爲這是必要的,因爲'GTag t'適合'DSum',但'GTag_ t'(沒有添加「Code」)不適用。但我可能是錯的。對於完整的上下文,我正在處理這個文件https://github.com/anderspapto/reflex-sumtype-render/blob/master/src/ReflexHelpers.hs,這是謎題的最後一個缺失部分。 – ajp