2016-02-26 170 views
1

的任意實例我想要一個函數能夠返回一個類型的所有可能的實例(不知道這是否是正確的單詞)。像這樣(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和字符串類型,並希望有一個解析函數來解析它們。

這可能嗎?

回答

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

雖然我希望能夠在其他數據類型中限制'T'類型。我不能要求所有'Integral'類型(例如)沒有類型變量。 –

+0

@snøreven在Haskell中,你不能隱藏多態類型。要麼你在任何地方都有類型變量,要麼你必須堅持具體的類型。在你的例子中,'fun'根據參數返回不同的類型,這也是不可能的(沒有一些新的依賴類型擴展)。 – lisyarus