在Haskell中,'a`可以是什么?

时间:2018-05-04 08:31:00

标签: haskell types typeclass type-constraints parametric-polymorphism

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

example :: 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可能没有&#39} ;在你输入一个值之前,我知道它是哪种类型,所以它需要知道你想要显示它,或者因为某些类型的变量不能自己扩展Show

2 个答案:

答案 0 :(得分:2)

这不是类型错误,这是语法错误。你只是错过了行尾的结束语。

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

答案 1 :(得分:2)

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

我认为发生的事情是你在没有类型签名的情况下在GHCi中尝试了你的定义,并且启动了单态限制。这就是为什么只有一个例子"工作"对你而言。

关于Show约束,因为您正在使用show :: Show a => a -> String功能,是的,这是必要的。

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