在Laemmel和SPJ的2003年Scrap Your Boilerplate paper中,第3页上有一段代码片段
mkT :: (Typeable a, Typeable b) => (b -> b) -> a -> a
mkT f = case cast f of
Just g -> g
Nothing -> id
然后论文解释
也就是说,如果x的类型与f的参数类型相同,则mkT f x将f应用于x
在本文前面的示例模式中,我认为必须将cast f
的类型与上面的类型Maybe (b -> b)
进行比较,以评估为Just g
,但这似乎不正确。
这里发生了什么cast f
的签名?
答案 0 :(得分:4)
cast
的类型是
cast :: (Typeable x, Typeable y) => x -> Maybe y
如果Nothing
和x
是不同的类型,它会生成y
,如果它们是相同的,则生成Just argument
。请注意,必须在使用y
时从调用上下文中确定结果类型cast
。如果不是,则编译因未解决的重载/模糊类型变量错误而失败。
在此特定示例中,类型是函数类型,参数为(b -> b)
,结果为(a -> a)
。所以
cast f :: Maybe (a -> a)
和mkT
也可以写成mkT = fromMaybe id . cast
。