list - Haskell 错误 - 没有由文字“1”引起的 (Num a) 实例
问题描述
我正在尝试创建一个在给定列表中的每个条目之前添加 1 的函数。我还没有完全掌握 Haskell 的语法,我想知道这段代码有什么问题。例如,我希望它返回列表 [1,1,1,2,1,3]
ins1 :: [a] -> [a]
ins1 [x] = [x]
ins1 (x:xs) = [1] ++ [x] ++ ins1(xs)
main = print(ins1 [1,2,3])
我得到错误:
• No instance for (Num a) arising from the literal ‘1’
Possible fix:
add (Num a) to the context of
the type signature for:
ins1 :: [a] -> [a]
• In the expression: 1
In the first argument of ‘(++)’, namely ‘[1]’
In the expression: [1] ++ [x] ++ ins1 (xs)
<interactive>:3:1: error:
• Variable not in scope: main
• Perhaps you meant ‘min’ (imported from Prelude)
解决方案
就像错误所说的那样,您使用ins1
,然后编写[1] ++ [x] ++ ...
.
Now1
是一个数字文字,因此它可以采用所有数字类型。因此1
有类型Num b => b
,结果[1]
有类型Num b => [b]
。
稍后您将列表附加到x
和递归,因此我们现在知道a ~ b
(a
并且b
是相同的类型)。所以我们必须在签名中添加一个类型约束a
:
ins1 :: Num a => [a] -> [a]
ins1 [x] = [x]
ins1 (x:xs) = [1] ++ [x] ++ ins1(xs)
这解决了编译错误,但可能不会生成你想要的。由于现在没有空列表的情况。实际上,[x]
模式和模式都适用于分别与仅具有一个元素和至少(x:xs)
一个元素的列表匹配的列表。
因此,我认为您的第一个子句实际上应该与空列表匹配:
ins1 :: Num a => [a] -> [a]
ins1 [] = []
ins1 (x:xs) = [1] ++ [x] ++ ins1(xs)
第二个子句也有一个低效率:你追加到一个元素的列表,所以我们可以在这里使用“ cons ”数据构造函数(:)
:
ins1 :: Num a => [a] -> [a]
ins1 [] = []
ins1 (x:xs) = 1 : x : ins1 xs
这将为原始列表中的每个元素1
插入一个,因此:
Prelude> ins1 [1, 4, 2, 5]
[1,1,1,4,1,2,1,5]
推荐阅读
- javascript - Js文件作为cypress中的fixture未加载
- c# - 为什么在循环中等待 SaveChangesAsync() 会导致短路并返回给调用者?
- prolog - 猴子和香蕉的解决方案在抓住香蕉后不会停止(Prolog)
- perl - 未定义的子程序 &main 使用图形包
- php - 如何使用 wordpress 中的 where 条件更新序列化表字段?
- c# - 正则表达式 - 忽略空格
- quarkus - AWS Secrets Manager:驱动程序不支持提供的 URL:jdbc-secretsmanager:postgresql
- wordpress - 如何在 WordPress 中通过 user_pass 向用户显示解密的密码?
- python - 异步 SQLAlchemy 示例中的“元”
- php - 为什么我不能在这个特性中使用我的实例?