2017-07-03 17 views

回答

5

下面是我在my earlier comment概述的想法代碼。您需要ScopedTypeVariables來告訴詳細說明哪種類型的電話eqT

infixl 4 <?> 
(<?>) :: forall a b. (Typeable a, Typeable b) => (a -> a) -> b -> Maybe b 
f <?> x = fmap (\Refl -> f x) (eqT :: Maybe (a :~: b)) 

h :: Typeable t => t -> Maybe t 
h x = f <?> x 
    <|> g <?> x 

可能需要一些解釋。 f <?> x嘗試將f應用於x,如果其類型匹配。 eqT :: (Typeable a, Typeable b) => Maybe (a :~: b)測試兩個Typeable字典,看看ab是否是相同的類型。如果是,則返回Just Refl,這是GADT證明它們是相同類型的。我在Refl上進行模式匹配,就像我在lambda中所做的那樣,將該等式納入範圍。在拉姆達的身體GHC知道a ~ b,所以我們可以安全地應用fx

+0

美麗的感謝,我正在尋找! – Clinton

+0

也許有用的是,你也可以使用更強的類型'(Typeable a,Typeable b)=>(a - > a) - > Maybe(b - > b)''來編寫''的版本。在這種類型中,''簡單地是'cast'。 – user2407038

+0

@ user2407038哦,當然!我甚至沒有想到這一點。然後我的答案中的''是'sequenceA。 cast'。太好了! –