帮助我理解将数字附加到字符串时的这个 Haskell (GHCI) 类型错误:(Num [Char])
这个周末我一直在尝试学习 Haskell,当我真正尝试编写一个递归函数(而不是仅仅从教程中输入一个)时,我得到了一个类型错误。
我非常感谢任何帮助理解(1)错误意味着什么(我不明白“修复”); (2) 为什么会抛出错误 - 我相当确定我在传递的类型方面没有犯任何错误。
我的代码:
tell :: (Show a) => [a] -> String
tell'in :: (Show a, Num n) => [a] -> n -> String -> (n, String)
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x
tell (x:xs) = "The list has " ++ n ++ " elements: " ++ s where (n, s) = (tell'in (xs) (1) (show x))
tell'in (x:[]) n s = ((n + 1), (s ++ " and " ++ (show x)))
tell'in (x:xs) n s = tell'in xs (n+1) (s ++ " and " ++ show x)
当我尝试将其加载到 GHCI 时出现错误:
[1 of 1] Compiling Main ( example.hs, interpreted )
example.hs:13:88:
Could not deduce (Num [Char]) arising from the literal `1'
from the context (Show a)
bound by the type signature for tell :: Show a => [a] -> String
at example.hs:(11,1)-(13,99)
Possible fix:
add (Num [Char]) to the context of
the type signature for tell :: Show a => [a] -> String
or add an instance declaration for (Num [Char])
In the second argument of `tell'in', namely `(1)'
In the expression: (tell'in (xs) (1) (show x))
In a pattern binding: (n, s) = (tell'in (xs) (1) (show x))
Failed, modules loaded: none.
Prelude>
I've been doing my annual attempt to learn Haskell this weekend, and as ever when I actually try to write a recursive function (rather than just type one in from a tutorial), I get a type error.
I'd very much appreciate any help understanding (1) what the error means (I don't understand the "fix"); and (2) why an error is being thrown at all - I'm fairly certain I'm not making any mistakes regarding the types being passed.
My code:
tell :: (Show a) => [a] -> String
tell'in :: (Show a, Num n) => [a] -> n -> String -> (n, String)
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x
tell (x:xs) = "The list has " ++ n ++ " elements: " ++ s where (n, s) = (tell'in (xs) (1) (show x))
tell'in (x:[]) n s = ((n + 1), (s ++ " and " ++ (show x)))
tell'in (x:xs) n s = tell'in xs (n+1) (s ++ " and " ++ show x)
And the error I get when I try to load this into GHCI:
[1 of 1] Compiling Main ( example.hs, interpreted )
example.hs:13:88:
Could not deduce (Num [Char]) arising from the literal `1'
from the context (Show a)
bound by the type signature for tell :: Show a => [a] -> String
at example.hs:(11,1)-(13,99)
Possible fix:
add (Num [Char]) to the context of
the type signature for tell :: Show a => [a] -> String
or add an instance declaration for (Num [Char])
In the second argument of `tell'in', namely `(1)'
In the expression: (tell'in (xs) (1) (show x))
In a pattern binding: (n, s) = (tell'in (xs) (1) (show x))
Failed, modules loaded: none.
Prelude>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
tell'in
返回一个Num n =>; n
,然后在最后一个方程中将其与String
(又名[Char]
)进行(++)
运算告诉
。您可能想在那里使用show n
而不是n
。tell'in
is returning aNum n => n
, which you are then(++)
ing with aString
(aka[Char]
) in the last equation fortell
. You probably want to useshow n
instead ofn
there.tell'in
的类型表示其返回值的第一个坐标与其第二个参数的类型相同。在tell
中,您使用数字作为第二个参数 (1
) 调用tell'in
,然后使用其返回的第一个坐标通过将值 (n
) 作为字符串附加到其他字符串。所以无论这个类型是什么,它必须同时是一个字符串和一个数字。该错误告诉您,字符串 ([Char]
) 无法被视为一种数字,当它尝试解释数字文字1 的含义时,就会出现这种情况
。你可能的意思是The type of
tell'in
says that the first coordinate of its return value will be the same type as its second argument. Intell
, you are callingtell'in
with a number as its second argument (1
), and then using the first coordinate of its return value (n
) as a string by appending it to other strings. So whatever this type is, it must simultaneously be a string and a number. The error is telling you that there is no way for a string ([Char]
) to be considered a kind of number, which arises when it tries to interpret the meaning of the numeric literal1
. You probably meant有一个通用方案来理解编译错误,如果它是某种类型不匹配:
您需要提供更具体的类型注释来缩小错误范围!
tell'in
和tell
已经有了类型:所以,你改变这个:
到这个:
现在,要么你已经看到错误,要么你尝试再次编译并得到一个更具体的错误消息。
无论如何,使用
::Int
而不是::Num n=>n
是个好主意,因为后者会泛化为::Integer< /code>,只要未指定确切类型。
Int
不大于一个机器字(32/64 位),因此它比任意大小的Integer
更快。There is a general scheme to understand the compile error, iff it is some type mismatch:
You need to supply more specific type annotations to narrow the error down!
tell'in
andtell
already have types:So, you change this:
To this:
Now, either you already see the error, or you try to compile again and have a more specific error message.
Anyway, it is a good idea to use
::Int
instead of::Num n=>n
, because the latter will generalize to::Integer
, whenever the exact type is not specified. TheInt
is not larger than one machine word (32/64bit) and therefore it is faster than the arbitrary-sizedInteger
.