我知道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
和OverlappingInstances
,但他们显然不会这样做。
答案 0 :(得分:12)
这是不可能的。 String
和[Char]
属于同一类型。没有办法区分这两种类型。使用OverlappingInstances
,您可以为String
和[a]
创建单独的实例,但[Char]
将始终使用String
的实例。
答案 1 :(得分:4)
为什么不为每种情况定义函数:
doSomethingString :: String -> String
doSomethingString = id
doSomethingChars :: (Char -> Char) -> String -> String
doSomethingChars f = ...
答案 2 :(得分:0)
如前所述,String
和[Char]
实际上是相同的。
您可以做的是定义newtype
。它包装了一个类型(免费,因为它在编译时被完全删除)并使其表现得像一个不同的类型。
newtype Blah = Blah String
instance Monoid Blah where
mempty = Blah ""
mappend (Blah a) (Blah b) = Blah $ a ++ "|" ++ b