I know that String is defined as [Char], yet I would like to make a difference between the two of them in a class instance. Is that possible with some clever trick other than using newtype to create a separate type? I would like to do something like:
class Something a where     
  doSomething :: a -> a
instance Something String where
  doSomething = id
instance (Something a) => Something [a] where
  doSomething = doSoemthingElse
And get different results when I call it with doSomething ("a" :: [Char]) and doSomething ("a" :: String).
I do know about FlexibleInstances and OverlappingInstances but they obviously don't cut the case.
That is not possible. String and [Char] are the same type. There is no way to distinguish between the two types. With OverlappingInstances you can create separate instances for String and [a], but [Char] will always use the instance for String.
Why don't you define functions for each case:
doSomethingString :: String -> String
doSomethingString = id
doSomethingChars :: (Char -> Char) -> String -> String
doSomethingChars f = ...
                        As said before, String and [Char] IS effectively the same.
What you can do though is defining a newtype. It wraps a type (at no-cost as it is completely removed when compiled) and makes it behave like a different type.
newtype Blah = Blah String
instance Monoid Blah where
  mempty = Blah ""
  mappend (Blah a) (Blah b) = Blah $ a ++ "|" ++ b 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With