Wenn Sie mit Data.Data
in Ordnung sind, funktioniert es für diesen Anwendungsfall, ist aber ein wenig klobig wegen der Int
Parameter.
{-# 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
Dann haben wir z.B.
λ 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]
Wenn Sie nicht Data.Data
verwenden möchten, Sie könnten in der Lage sein, dies zu tun mit GHC.Genertcs
und -XDefaultSignatures
FWIW, würden Sie nicht mit irgendetwas davon zu tun haben, wenn Sie konnte ABC Refactoring, so dass die A, B, C-Tags ihre eigene Art ...
waren
data ABCTagged = ABCTagged ABC Int deriving Show
data ABC = A | B | C deriving (Show, Eq, Ord, Enum. Bounded)
... dann nur enumFrom minBound :: [ABC]
verwenden, um die gesamte Liste zu bekommen. Einfach! Nicht sicher, wie machbar das für dich ist.
Führt ['Arbitrary'] (https://hackage.haskell.org/package/QuickCheck-2.9.1/docs/Test-QuickCheck-Arbitrary.html) bereits das aus, was Sie wollen (ohne auf Daten zu setzen). Daten')? Welche Argumente würden Sie sonst den Konstrukteuren geben? – Alec
Grundsätzlich möchte ich eine Liste von Zahlen mit der Liste der Konstruktoren verbinden. Aber ich möchte die Liste der Konstruktoren dynamisch abrufen. – kurzweil4
'Arbitrary' hilft mir in diesem Fall nicht. Ich möchte nicht zufällig Daten generieren. Ich möchte eine Bedingung für jede Dateninstanz testen. – kurzweil4