2
我大概要達到以下情況的匹配:採用分型,有效防止不同類型
f :: a -> a
g :: b -> b
h :: Typeable t => t -> Maybe t
h x = case x of
(x is of type a) -> Just (f x)
(x is of type b) -> Just (g x)
_ -> Nothing
我大概要達到以下情況的匹配:採用分型,有效防止不同類型
f :: a -> a
g :: b -> b
h :: Typeable t => t -> Maybe t
h x = case x of
(x is of type a) -> Just (f x)
(x is of type b) -> Just (g x)
_ -> Nothing
下面是我在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
字典,看看a
和b
是否是相同的類型。如果是,則返回Just Refl
,這是GADT證明它們是相同類型的。我在Refl
上進行模式匹配,就像我在lambda中所做的那樣,將該等式納入範圍。在拉姆達的身體GHC知道a ~ b
,所以我們可以安全地應用f
x
。
美麗的感謝,我正在尋找! – Clinton
也許有用的是,你也可以使用更強的類型'(Typeable a,Typeable b)=>(a - > a) - > Maybe(b - > b)''來編寫'>'的版本。在這種類型中,'>'簡單地是'cast'。 – user2407038
@ user2407038哦,當然!我甚至沒有想到這一點。然後我的答案中的'>'是'sequenceA。 cast'。太好了! –