
On Thu, Oct 4, 2012 at 10:58 PM, Tyson Whitehead
On October 4, 2012 13:48:42 Ben Millwood wrote:
On Thu, Oct 4, 2012 at 5:03 PM, Tyson Whitehead
import Data.Typeable import Data.Maybe
magic :: Typeable a => a -> a magic x =
case cast x of
Just x -> cast $ fromJust $ x ++ " (ta da)" _ -> x
gives you id except for strings.
ITYM fromJust $ cast rather than the other way around. But the ability to cast like this does not give you access to data structure you didn't already have – it does not violate abstraction.
Indeed. I did mean those to be swapped. Thanks for picking up on that.
I have to confess though, I'm not really following on how this doesn't give you access to data structure you didn't already have? Perhaps we are not thinking of the same thing when you say "access to data structure"?
Doesn't the above "a -> a" function (under the proposed system where you don't need a "Typeable a" constraint") take apart some of its argument
magic 1 ---> 1 magic 2 ---> 2 magic "hello world" ---> "hello world (ta da)"
Doesn't this mean then that whole "theorems for free" stuff goes out the window? Isn't its whole basis the idea that unconstrained types are actually statements that those arguments won't be constructed/deconstructed?
Thanks! -Tyson
You still need a Typeable constraint! There would *not* be an instance Typeable a there would only be instance Typeable Foo instance Typeable Bar instance Typeable Baz ... for every concrete type that is declared. But there's no universal instance, and there's no way to take advantage of the fact that every particular type has an instance. If you had foo :: a -> a and it was doing things like you described, that would be a big problem! But as discussed previously, that _will not_ happen. You will still need a Typeable constraint to be able to use typeOf and cast. On the other hand if you have bar :: Typeable a => a -> a and it did those, it's unremarkable (it can already do those things). That's a very different type signature from what 'foo' has. The change would be that you could you use 'bar' with any _concrete_ types you supply (so 'Int', or 'Bool', or 'MyData', 'Foo', 'Bar', or 'Baz', but not 'a' or 'b'), instead of only the ones that explicitly have 'deriving Typeable'. The question is whether that's bad in any way -- whether there's any case where you do *not* want a particular type to be an instance of Typeable. The classic case where you do not want a type to implement a class is when the instance would expose implementation details of the type which you want to keep hidden (for example if want to hide data constructors, Data or Generic would be purpose-defeating). So the questions are: (1) Does Typeable expose anything internal to a type which you might want to keep hidden (I don't think so) (2) Are there any other reasons you might want to avoid having an instance (I can't think of any) -- Your ship was destroyed in a monadic eruption.