Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top