让函数返回类型

问题描述:

的任意实例我想要一个函数能够返回一个类型的所有可能的实例(不知道这是否是正确的单词)。像这样(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和字符串类型,并希望有一个解析函数来解析它们。

这可能吗?

你可以使用一个存在的类型的包装。

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 [email protected](TInt _)) = Just x 
foo _    = Nothing 

对此的通常解决方案只是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 
+0

虽然我希望能够在其他数据类型中限制'T'类型。我不能要求所有'Integral'类型(例如)没有类型变量。 –

+0

@snøreven在Haskell中,你不能隐藏多态类型。要么你在任何地方都有类型变量,要么你必须坚持具体的类型。在你的例子中,'fun'根据参数返回不同的类型,这也是不可能的(没有一些新的依赖类型扩展)。 – lisyarus