[英]Can't make String an instance of a class in Haskell
我正在试图理解Haskell中的类。 我写了一些愚蠢的代码来获取它。 我写了一个名为Slang
的类,它有一个函数。 当我将Integer作为我的类的一个实例时,它工作正常。 但是当我将String作为我的类的一个实例时,它将无法编译。 我一直在根据错误输出告诉我的程序而烦恼,但无济于事。 我知道它为什么有用......
以下是错误后面的代码:
module Practice where
class Slang s where
slangify :: s -> String
instance Slang Integer where
slangify int = "yo"
instance Slang String where -- When I take this segment out, it works fine
slangify str = "bro"
错误:
Prelude> :load Practice
[1 of 1] Compiling Practice ( Practice.hs, interpreted )
Practice.hs:9:10:
Illegal instance declaration for `Slang String'
(All instance types must be of the form (T t1 ... tn)
where T is not a synonym.
Use -XTypeSynonymInstances if you want to disable this.)
In the instance declaration for `Slang String'
Failed, modules loaded: none.
Prelude>
问题是String不是像Integer这样的基类型。 你要做的实际上是
instance Slang [Char] where
slangify str = "bro"
但是,Haskell98禁止使用这种类型类型,以便简化操作并使人们更难以编写重叠的实例
instance Slang [a] where
-- Strings would also fit this definition.
slangify list = "some list"
无论如何,正如错误消息所示,您可以通过启用FlexibleInstances扩展来绕过此限制。
我在我的Haskell文献(也就是我现在的圣经)中做了一些研究,并找到了一个有效解决我问题的例子。
基本上,在这个变通方法中,你将Char
设置为类的一个实例(在本书的例子中它被称为Visible
)然后你可以设置[chars]
又名一个String,作为类的一个实例,只有规则,类型变量chars
是“可见”的实例。 如果你看下面的代码,它会更容易理解:
module Practice where
class Visible a where
toString :: a -> String
size :: a -> Int
instance Visible Char where
toString ch = [ch]
size _ = 1
instance Visible a => Visible [a] where
toString = concat . map toString
size = foldr (+) 1 . map size
我的GHCi负载和函数调用:
*Practice> :l Practice
[1 of 1] Compiling Practice ( Practice.hs, interpreted )
Ok, modules loaded: Practice.
*Practice> size "I love Stack!"
14
*Practice>
找到了!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.