Hello! The paper http://research.microsoft.com/~simonpj/papers/hmap/ by Ralf Laemmel and Simon Peyton Jones gave a reference implementation of a 'cast' function. Here's another implementation:
cast:: (Show a, Read b) => a -> Maybe b cast = read_as . show where read_as s = case readsPrec 1 s of [(r,[])] -> Just r _ -> Nothing -- Tests from the hmap paper -- *Main> (cast 'a') :: Maybe Char -- Just 'a' -- *Main> (cast 'a') :: Maybe Int -- Nothing -- *Main> (cast 'a') :: Maybe Bool -- Nothing -- *Main> (cast True) :: Maybe Bool -- Just True -- *Main> (cast "True") :: Maybe Bool -- Nothing -- *Main> (cast "True") :: Maybe Int -- Nothing -- *Main> (cast "True") :: Maybe String -- Just "True" -- Additional tests -- *Main> (cast [1,2,3])::Maybe [Int] -- Just [1,2,3] -- *Main> (cast [1,2,3])::Maybe [Integer] -- Just [1,2,3] -- *Main> (cast [1,2,3])::Maybe [Float] -- Just [1.0,2.0,3.0] -- *Main> (cast (Just True)) :: Maybe Int -- Nothing -- *Main> (cast (Just True)) :: Maybe (Maybe Bool) -- Just (Just True) -- *Main> (cast (Nothing::Maybe Bool)) :: Maybe (Maybe Bool) -- Just Nothing -- *Main> (cast (Nothing::Maybe Bool)) :: Maybe (Maybe Int) -- Just Nothing -- *Main> (cast (Nothing::Maybe Bool)) :: Maybe (Maybe Char) -- Just Nothing Granted, the cast function here cannot handle exponential types. OTH, the cast function given here can cast an Int to an Integer or to a Float. Most of all, the cast function here is implemented entirely in Haskell 98, with no extensions whatsoever -- not existential types, let alone unsafeCoerce. An aside: OCaml has a function called Obj.magic: 'a -> 'b, which is unsafeCoerce with a positive name. If OCaml did not provide that function, it can be easily emulated: # let door_to_hell x = Marshal.from_string (Marshal.to_string () []) 0;; val door_to_hell : 'a -> 'b = <fun> This is a terminating function with a signature a->b. It critically relies on marshalling and unmarshalling. BTW, the function breaks all kinds of free theorems: # let (fake_id: 'a->'a) = function x -> door_to_hell x;; val fake_id : 'a -> 'a = <fun> # fake_id 123;; - : int = 0 We can write a totally polymorphic terminating function a->a that is patently not the identity. _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell