使用Typeable可以有效匹配不同类型的大小写 [英] Using Typeable to effectively case match against different types

查看:101
本文介绍了使用Typeable可以有效匹配不同类型的大小写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我大致想达到以下目的:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆