帮助我理解将数字附加到字符串时的这个 Haskell (GHCI) 类型错误:(Num [Char])

发布于 2024-11-14 03:27:47 字数 1356 浏览 3 评论 0原文

这个周末我一直在尝试学习 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

女皇必胜 2024-11-21 03:27:47

tell'in 返回一个 Num n =>; n,然后在最后一个方程中将其与 String(又名 [Char])进行 (++) 运算告诉。您可能想在那里使用 show n 而不是 n

tell'in is returning a Num n => n, which you are then (++)ing with a String (aka [Char]) in the last equation for tell. You probably want to use show n instead of n there.

泛滥成性 2024-11-21 03:27:47

tell'in 的类型表示其返回值的第一个坐标与其第二个参数的类型相同。在 tell 中,您使用数字作为第二个参数 (1) 调用 tell'in,然后使用其返回的第一个坐标通过将值 (n) 作为字符串附加到其他字符串。所以无论这个类型是什么,它必须同时是一个字符串和一个数字。该错误告诉您,字符串 ([Char]) 无法被视为一种数字,当它尝试解释数字文字 1 的含义时,就会出现这种情况。你可能的意思是

"The list has " ++ show n ++ " elements: " ++ ...

The type of tell'in says that the first coordinate of its return value will be the same type as its second argument. In tell, you are calling tell'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 literal 1. You probably meant

"The list has " ++ show n ++ " elements: " ++ ...
晒暮凉 2024-11-21 03:27:47

有一个通用方案来理解编译错误,如果它是某种类型不匹配:
您需要提供更具体的类型注释来缩小错误范围!

tell'intell 已经有了类型:

tell :: (Show a) => [a] -> String  
tell'in :: (Show a, Num n) => [a] -> n -> String -> (n, String)

所以,你改变这个:

tell (x:xs) = "The list has " ++ n ++ " elements: " ++ s
    where (n, s) = tell'in (xs) (1) (show x)) 

到这个:

--   vvvvvvvvvvvvvvvvvvvvvvv                      vvvvvvvv
tell ((x:xs)::(Show a=>[a])) = "The list has " ++ (n::Int) ++ " elements: " ++ s
    where (n::Int, s::String) = tell'in (xs) (1::Int) (show x)) 
--        ^^^^^^^^^^^^^^^^^^^^               ^^^^^^^^

现在,要么你已经看到错误,要么你尝试再次编译并得到一个更具体的错误消息。


无论如何,使用 ::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 and tell already have types:

tell :: (Show a) => [a] -> String  
tell'in :: (Show a, Num n) => [a] -> n -> String -> (n, String)

So, you change this:

tell (x:xs) = "The list has " ++ n ++ " elements: " ++ s
    where (n, s) = tell'in (xs) (1) (show x)) 

To this:

--   vvvvvvvvvvvvvvvvvvvvvvv                      vvvvvvvv
tell ((x:xs)::(Show a=>[a])) = "The list has " ++ (n::Int) ++ " elements: " ++ s
    where (n::Int, s::String) = tell'in (xs) (1::Int) (show x)) 
--        ^^^^^^^^^^^^^^^^^^^^               ^^^^^^^^

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. The Int is not larger than one machine word (32/64bit) and therefore it is faster than the arbitrary-sized Integer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文