我有數據類型Tup2List
和GTag
(從答案How can I produce a Tag type for any datatype for use with DSum, without Template Haskell?)我該如何編寫這個GEq實例?
我想寫一個GEq
實例GTag t
,我認爲還需要有一個爲Tup2List
。我怎樣才能寫這個實例?
我對它爲什麼不起作用的猜測是因爲沒有這樣的東西作爲部分Refl
- 你需要一次性爲整個結構匹配編譯器給你的Refl,而我試圖只是解開最外層的構造函數然後遞歸。
這是我的代碼,undefined
填寫了我不知道該怎麼寫的部分。
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
module Foo where
import Data.GADT.Compare
import Generics.SOP
import qualified GHC.Generics as GHC
data Tup2List :: * -> [*] -> * where
Tup0 :: Tup2List() '[]
Tup1 :: Tup2List x '[ x ]
TupS :: Tup2List r (x ': xs) -> Tup2List (a, r) (a ': x ': xs)
instance GEq (Tup2List t) where
geq Tup0 Tup0 = Just Refl
geq Tup1 Tup1 = Just Refl
geq (TupS x) (TupS y) =
case x `geq` y of
Just Refl -> Just Refl
Nothing -> Nothing
newtype GTag t i = GTag { unTag :: NS (Tup2List i) (Code t) }
instance GEq (GTag t) where
geq (GTag (Z x)) (GTag (Z y)) = undefined -- x `geq` y
geq (GTag (S _)) (GTag (Z _)) = Nothing
geq (GTag (Z _)) (GTag (S _)) = Nothing
geq (GTag (S x)) (GTag (S y)) = undefined -- x `geq` y
編輯:我改變了我的數據類型,但我仍然面臨同樣的核心問題。目前的定義是
data Quux i xs where Quux :: Quux (NP I xs) xs
newtype GTag t i = GTag { unTag :: NS (Quux i) (Code t) }
instance GEq (GTag t) where
-- I don't know how to do this
geq (GTag (S x)) (GTag (S y)) = undefined
真棒。而且我能夠毫不費力地概括出'[a]約束(推理是因爲這段代碼是爲了進入一個庫,並且應該與任意的最終用戶類型一起工作)。 – ajp
我碰到下一個絆腳石 - https://stackoverflow.com/questions/40710801/how-can-i-write-function-to-convert-generic-type-to-tag-shaped-type-for-使用-與 – ajp