Reputation: 1974
I want a function to be able to return all possible instances (not sure if that's the right word) of a type. Like this (fun
not working):
data T a where
TInt :: Int -> T Int
TStr :: String -> T String
fun :: Int -> T (forall a. a)
fun a | a >= 5 = TStr "a lot"
| otherwise = TInt a
My end goal is to have an alias type SomeT
that stands for arbitrary T
.
I want to use this to parse type declarations of a DSL. I have int and string types and want to have one parsing function that parses them all.
Is this possible?
Upvotes: 1
Views: 80
Reputation: 116174
You could use an existential type wrapper.
data T a where
TInt :: Int -> T Int
TStr :: String -> T String
data SomeT where
S :: T a -> SomeT
fun :: Int -> SomeT
fun a | a >= 5 = S $ TStr "a lot"
| otherwise = S $ TInt a
foo :: SomeT -> Maybe (T Int)
foo (S x@(TInt _)) = Just x
foo _ = Nothing
Upvotes: 3
Reputation: 15568
The usual solution to this are simply algebraic data types.
data T = TInt Int | TStr String
fun :: Int -> T
fun a | a >= 5 = TStr "a lot"
| othrwise = TInt a
However, your exact problem can be solved, using typeclasses for ad-hoc polymorphic behavior:
class TT a where
tt :: a -> T a
instance TT Int where
tt = TInt
instance TT String where
tt = TString
fun :: (TT a) => Int -> T a
fun a | a >= 5 = tt "a lot"
| otherwise = tt a
Upvotes: 0