Haskell 区分字符串和[Char]

Haskell 区分字符串和[Char],haskell,types,Haskell,Types,我知道String被定义为[Char],但我想在类实例中对这两个字符串进行区分。除了使用newtype创建一个单独的类型之外,还有其他聪明的技巧可以做到这一点吗?我想做一些类似的事情: class Something a where doSomething :: a -> a instance Something String where doSomething = id instance (Something a) => Something [a] where

我知道String被定义为[Char],但我想在类实例中对这两个字符串进行区分。除了使用newtype创建一个单独的类型之外,还有其他聪明的技巧可以做到这一点吗?我想做一些类似的事情:

class Something a where     
  doSomething :: a -> a

instance Something String where
  doSomething = id

instance (Something a) => Something [a] where
  doSomething = doSoemthingElse
当我用
doSomething(“a::[Char])
doSomething(“a::String”)调用它时,会得到不同的结果


我确实知道FlexibleInstances和重叠实例,但它们显然不能解决问题。

这是不可能的<代码>字符串
[Char]
是相同的类型。无法区分这两种类型。使用
OverlappingInstances
可以为
String
[a]
创建单独的实例,但是
[Char]
将始终为
String
使用实例,为什么不为每种情况定义函数呢:

doSomethingString :: String -> String
doSomethingString = id

doSomethingChars :: (Char -> Char) -> String -> String
doSomethingChars f = ...

如前所述,
String
[Char]
实际上是相同的

但您可以做的是定义一个
newtype
。它包装了一个类型(因为编译时它会被完全删除,所以不会产生任何成本),并使它的行为与其他类型类似

newtype Blah = Blah String

instance Monoid Blah where
  mempty = Blah ""
  mappend (Blah a) (Blah b) = Blah $ a ++ "|" ++ b 

您不能这样做,在编译器级别,
[Char]
字符串
是完全相同的东西。键入同义词名称将消失。如果您必须以任何方式显式注释,为什么不使用newtype呢对于
String
使用Haskell 98,您可能可以做Show类所做的事情,并使用它。问题是,据我所知,它总是调用
String
的实例,因为
type String=[Char]
,所以它并不能真正解决我的问题。@qwe2您是对的,但我认为理智的行为,而不是问题:这是我所期待的。不过,你认为我解决这个问题的最好办法是什么?因为我所能想到的就是引入一个
newtype
使它们分离,但这并不像我希望的那样漂亮。使用一个newtype。这是std-libs提供的更好的方法:如果处理文本数据,请使用
Text
datatype。在这个意义上,您可以认为它是一个围绕字符串的预烘焙的新型包装器,它恰巧有一个极好的API和更好的性能。(或者,如果有更多的实例,而不仅仅是<代码> [a]代码>)一个字符串的函数:<代码> DoMothTimeString ,并保持类型类。