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