使用Typeable可以有效匹配不同类型的大小写 [英] Using Typeable to effectively case match against different types
问题描述
f :: a - > a
g :: b - > b
h :: Typeable t => t - >也许t
h x =案例x的
(x是类型a) - > Just(f x)
(x是类型b) - > Just(g x)
_ - > Nothing
这是我在我之前的评论。你需要 ScopedTypeVariables
来告诉详细说明哪种类型可以调用 eqT
。
infixl 4<>
(<>):: forall a b。 (可键入a,可键入b)=> (a - > a) - > b - >也许b
f<> x = fmap(\ Refl - > f x)(eqT :: Maybe(a:〜:b))
h :: Typeable t => t - >也许t
h x = f<> x
< |> g<> x
可能需要一些解释。 f <?>如果类型匹配,x
会尝试将 f
应用于 x
。 eqT: :(可键入a,可键入b)=>也许(a:〜:b)
会测试两个 Typeable
字典以查看 a
和 b
是相同的类型。如果是,它会返回 Just Refl
,这是GADT证明它们是同一类型的。在 Refl
上进行模式匹配,就像我在lambda中做的那样,将相等性纳入范围。在lambda体中,GHC知道 a〜b
,所以我们可以安全地将 f
应用于 x
。
I roughly want to achieve the following:
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
Here's code for the idea I outlined in my earlier comment. You need ScopedTypeVariables
to tell the elaborator at which type to call 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
Probably warrants some explanation. f <?> x
attempts to apply f
to x
, if its type matches. eqT :: (Typeable a, Typeable b) => Maybe (a :~: b)
tests the two Typeable
dictionaries to see if a
and b
are the same type. If they are, it returns Just Refl
, a GADT proof that they are the same type. Pattern matching on Refl
, as I did in the lambda, brings that equality into scope. In the body of the lambda GHC knows a ~ b
, so we can safely apply f
to x
.
这篇关于使用Typeable可以有效匹配不同类型的大小写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!