10

我知道 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])and调用它时会得到不同的结果doSomething ("a" :: String)

我确实知道FlexibleInstancesOverlappingInstances但他们显然没有解决这个问题。

4

3 回答 3

14

这是不可能的。String并且[Char]是同一类型。没有办法区分这两种类型。您可以为和OverlappingInstances创建单独的实例String[a][Char]将始终使用 的实例String

于 2013-10-08T21:24:20.290 回答
4

为什么不为每种情况定义函数:

doSomethingString :: String -> String
doSomethingString = id

doSomethingChars :: (Char -> Char) -> String -> String
doSomethingChars f = ...
于 2013-10-08T21:36:28.573 回答
1

如前所述,String[Char]IS 实际上是一样的。

你可以做的是定义一个newtype. 它包装了一个类型(免费,因为它在编译时被完全删除)并使其表现得像一个不同的类型。

newtype Blah = Blah String

instance Monoid Blah where
  mempty = Blah ""
  mappend (Blah a) (Blah b) = Blah $ a ++ "|" ++ b 
于 2013-10-09T09:20:12.477 回答