獲取數據構造的名單我有一個這樣的數據類型:動態地從類型
data ABCS = A Int | B Int | ... | Z Int deriving (Data, Typeable)
在測試中,我要動態提取所有構造函數,每個構造做一個實例,然後運行考試。
我一直在尋找通過Data.Typeable
和Data.Data
,但我還沒有看到/明白如何做到這一點,只有類型(ABC)開始。
非常感謝幫助。
獲取數據構造的名單我有一個這樣的數據類型:動態地從類型
data ABCS = A Int | B Int | ... | Z Int deriving (Data, Typeable)
在測試中,我要動態提取所有構造函數,每個構造做一個實例,然後運行考試。
我一直在尋找通過Data.Typeable
和Data.Data
,但我還沒有看到/明白如何做到這一點,只有類型(ABC)開始。
非常感謝幫助。
如果您可以使用Data.Data
,它適用於此用例,但由於參數Int
有點笨重。
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Data
import Data.Typeable
allCtors :: forall a. Data a => [Int -> a]
allCtors = map observeCtor $ dataTypeConstrs $ dataTypeOf (undefined :: a)
where
observeCtor :: Constr -> Int -> a
observeCtor c i = fromJust $ fromConstrM (cast i) c
然後,例如,
λ data ABC = A Int | B Int | C Int deriving (Show, Data, Typeable)
data ABC = A Int | B Int | C Int
λ map ($ 2) allCtors :: [ABC]
[A 2,B 2,C 2]
如果你不想使用Data.Data
,你可能能夠與GHC.Genertcs
和-XDefaultSignatures
FWIW要做到這一點,你就不必處理是否有任何這你可以重構ABC從而使A,B,C標籤是他們自己的類型......
data ABCTagged = ABCTagged ABC Int deriving Show
data ABC = A | B | C deriving (Show, Eq, Ord, Enum. Bounded)
...那麼就使用enumFrom minBound :: [ABC]
讓整個列表。簡單!不知道這對你有多可行。
數據類型不是我的實際數據類型。這是我能做出的最簡單的例子,可以表達我正在努力完成的事情。所以,標記的例子不適合我。但謝謝你的建議。 – kurzweil4
爲了我自己的理解,我逐個分解你的答案,當我執行這個'fromConstrM(Just 10 :: Maybe Int)ctor'我得到了'無法將類型'd'與'Int' 'd'是一個剛性類型變量,由 綁定,上下文預期類型: forall d。 Data d => Maybe d at
好的,我已經部分想到了:'讓c = cast 10 :: forall d。數據d =>也許d'然後'fromConstrM c ctorA',但我得到'只是()' – kurzweil4
['Arbitrary'](https://hackage.haskell.org/package/QuickCheck-2.9.1/docs/Test-QuickCheck-Arbitrary.html)是否已經做到了你想要的(不訴諸於'數據。 Data')?否則,你想給構造函數提供什麼參數? – Alec
基本上我想用構造函數列表連接數字列表。但我想動態獲取構造函數列表。 – kurzweil4
'Arbitrary'在這種情況下不能幫助我。我不想隨機生成數據。我想測試每個數據實例的條件。 – kurzweil4