我希望函数能够返回一个类型的所有可能实例(不确定这是否是正确的单词)。像这样(fun
不工作):
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
我的最终目标是使用代表任意SomeT
的别名类型T
。
我想用它来解析DSL的类型声明。我有int和string类型,并希望有一个解析它们的解析函数。
这可能吗?
答案 0 :(得分:3)
您可以使用存在类型包装器。
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
答案 1 :(得分:0)
通常的解决方案只是algebraic data types。
data T = TInt Int | TStr String
fun :: Int -> T
fun a | a >= 5 = TStr "a lot"
| othrwise = TInt a
但是,使用类型规则进行特殊的多态行为可以解决您的确切问题:
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