Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differentiate between String and [Char]

Tags:

types

haskell

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.

like image 299
qwe2 Avatar asked Oct 08 '13 21:10

qwe2


3 Answers

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.

like image 126
Dirk Holsopple Avatar answered Oct 07 '22 16:10

Dirk Holsopple


Why don't you define functions for each case:

doSomethingString :: String -> String
doSomethingString = id

doSomethingChars :: (Char -> Char) -> String -> String
doSomethingChars f = ...
like image 44
Gabriella Gonzalez Avatar answered Oct 07 '22 16:10

Gabriella Gonzalez


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 
like image 30
tomferon Avatar answered Oct 07 '22 17:10

tomferon