让函数返回类型
问题描述:
的任意实例我想要一个函数能够返回一个类型的所有可能的实例(不知道这是否是正确的单词)。像这样(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
虽然我希望能够在其他数据类型中限制'T'类型。我不能要求所有'Integral'类型(例如)没有类型变量。 –
@snøreven在Haskell中,你不能隐藏多态类型。要么你在任何地方都有类型变量,要么你必须坚持具体的类型。在你的例子中,'fun'根据参数返回不同的类型,这也是不可能的(没有一些新的依赖类型扩展)。 – lisyarus