在 Haskell 中,`a` 可以是任何东西吗?

In Haskell, could `a` be anything?

虽然我一直在阅读文档,但我一直认为 a 可以是以下任何内容:

example :: a -> a 

'a' 可以是 CharStringIntInteger.

当然,如果我输入:

example :: [a] -> a

输入应该是一个列表,但可以是任何列表:["ab", "cd"][1,2]['s', 'c'].

但是在我的代码中:

toString' :: (Show a) => [a] -> String
toString' [] = "empty"
toString' [x] = " and " ++ show x
toString' (x:y:[]) = show x ++ toString' [y]
toString' (x:xs) = show x ++ ", " ++ toString' xs

它应该有效,但并不总是有效:

Prelude> toString' ['a', 'b', 'c']  -- Works
Prelude> toString' [1, 2, 3]  -- Don't work
Prelude> toString' ["abc", "bc", "efc"] -- Don't work

我不明白为什么我需要添加 Show 约束,如果通常在本书的示例中我不需要它。

更新

好吧,不是,不是["abc", "bc", "efc]["abc", "bc", "efc"]的变化,其实代码里我写对了,只是这里我先打错了

关于Show,如果有必要在这段代码中使用它,你能回答我吗?

更新 2

我不知道如果你投反对票它是否有用,或者它会被关闭,但无论如何

如果我在最后一行使用以下代码,代码将运行得更好:

toString' (x:xs) = show x ++ ", " ++ (toString' xs)

但仍然不明白为什么我需要 Show(我的意思是,为什么我不能从代码中删除它?)

更新 3

我看到 Show 的错误,如果你使用变量类型 a 而不是 String,你需要 Show,也许是因为它可以 Haskell 在你输入一个值之前不知道它是哪种类型,所以它需要知道你想要显示它,或者因为有些类型的变量不会自己扩展 Show .

这不是类型错误,这是 语法 错误。您只是漏掉了行尾的结束引号。

toString' ["abc", "bc", "efc"]
                            ^

我刚刚将您的代码复制到我的 GHCi 中,您的所有三个示例都有效。 Prelude> toString' ["abc", "bc", "efc"] 产生 "\"abc\", \"bc\" and \"efc\""

我想发生的事情是你在没有类型签名的情况下在 GHCi 中尝试了你的定义,并且单态限制开始了。这就是为什么只有一个例子 "worked" 适合你。

关于Show约束,既然你用的是show :: Show a => a -> String函数,是的,这是必须的。

如果您要定义 特定 版本 toString'Int :: [Int] -> String(或 Char),那将没有问题。但是您是为 [a] 定义它——为 any a。由于您正在使用 show (x :: a),因此此函数接受的 any a 必须属于 Show。这表示为 (Show a) => .....