2
votes

In the 2003 Scrap Your Boilerplate paper by Laemmel and SPJ there is a code snippet on page 3

mkT :: (Typeable a, Typeable b) => (b -> b) -> a -> a
mkT f = case cast f of
   Just g -> g
   Nothing -> id

and then the paper explains

That is, mkT f x applies f to x if x's type is the same as f's argument type

Following in the pattern of the preceding examples in the paper, I would think the type of cast f would have to be compared with the type Maybe (b -> b) for the above to evaluate to Just g, but this seems incorrect.

What is going on here with the signature of cast f?

1

1 Answers

4
votes

The type of castis

cast :: (Typeable x, Typeable y) => x -> Maybe y

it produces Nothing if x and y are different types and Just argument if they are the same. Note that the result type, y must be determined from the calling context when cast is used. If it isn't, compilation fails with an unresolved overloading/ambiguous type variable error.

In this particular example, the types are function types, (b -> b) for the argument, and (a -> a) for the result. So

cast f :: Maybe (a -> a)

and mkT could also be written mkT = fromMaybe id . cast.