虽然我一直在阅读文档,但我一直认为a
可以是任何内容:
example :: a -> a
'一个'可以是Char
,String
,Int
,Integer
。
当然如果我把:
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
答案 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) => ....
。