Haskell 计算列表的元素
我尝试创建这段代码来计算记录数量并打印它们,但我似乎无法使其工作,我不断收到有关将函数 reportReg 应用于一个参数但其类型 [String] 没有的错误。
report :: [[String]] -> String -> [String]
report (x:xs) typ = do
case typ of
"registrations" -> reportReg (map head xs)
"completions" -> reportReg (map head xs)
reportReg :: [String]
reportReg [x] = do
print x
print 1
reportReg (x:xs) = do
let count = instances x (x:xs)
print x
print count
let newlist = filter (==x) (x:xs)
reportReg newlist
instances::String->[String]->Int
instances x [] = 0
instances x (y:ys)
| x==y = 1+(instances x ys)
| otherwise = instances x ys
另外,有没有更简单的方法来做到这一点?
I have this code that I tried to create to count amount of records and print them, I cant seem to get it working I constantly get errors about a function reportReg being applied to one argument but its type [String] having none.
report :: [[String]] -> String -> [String]
report (x:xs) typ = do
case typ of
"registrations" -> reportReg (map head xs)
"completions" -> reportReg (map head xs)
reportReg :: [String]
reportReg [x] = do
print x
print 1
reportReg (x:xs) = do
let count = instances x (x:xs)
print x
print count
let newlist = filter (==x) (x:xs)
reportReg newlist
instances::String->[String]->Int
instances x [] = 0
instances x (y:ys)
| x==y = 1+(instances x ys)
| otherwise = instances x ys
Also, is there an easier way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题:
您给了
reportReg
一种字符串列表类型:这只是一个值,或者是一个包含 0 个参数的函数。这解释了你所得到的错误——试图给它一个参数,但它不需要任何参数。
解决方案:
看起来你想在
reportReg
中进行IO操作,所以你应该更改类型注释:-- or --
问题:
报告
的返回类型是错误的。它必须与reportReg
相同。但是reportReg :: String -> IO(),而report::[[String]] ->字符串 -> [字符串]
!几个可能的解决方案:
reportReg
中删除IO操作,使其类型为[String] -> [字符串]
。我强烈建议这样做——任何语言中的 IO 总是一种痛苦,但 Haskell 的酷之处在于它让你感受到痛苦——从而激励你尽可能避免 IO!报告
类型更改为[[String]] ->字符串 -> IO()
懒人的解决方案:
我将你的代码复制到一个文本文件中,删除注释(不做其他更改),并将其加载到
ghci
中:它有效——Haskell 推断类型! 但它可能不会达到您想要的效果。
Problem:
You've given
reportReg
a type of list of string:This is simply a value, or a function of 0 arguments. That explains the error you were getting -- trying to give it an argument, but it takes none.
Solutions:
It looks like you want to do IO actions in
reportReg
, so you should change the type annotation:-- or --
Problem:
report
's return type is wrong. It has to be the same as that ofreportReg
. ButreportReg :: String -> IO ()
, whereasreport :: [[String]] -> String -> [String]
!A couple possible solutions:
reportReg
, so that its type is[String] -> [String]
. I'd strongly suggest doing this -- IO in any language is always a pain, but the cool thing about Haskell is that it makes you feel the pain -- thereby giving you an incentive to avoid IO as much as possible!report
to[[String]] -> String -> IO ()
Lazy man's solution:
I copied your code into a text file, removed the annotations (making no other changes), and loaded it into
ghci
:It works -- Haskell infers the types! But it may not do what you want.
我想我明白发生了什么事。
声明
reportReg
是一个字符串列表。但是您希望reportReg
成为一个函数(在类型中用->
标记),它采用一个列表字符串:现在唯一的问题是用什么来代替
???
——reportReg
返回什么?这就是 Haskell 与其他语言的不同之处。它返回一个I/O 操作。它是一个将字符串列表映射到操作的函数——即,要做的事情,而不是要返回的值(所以它确实返回值——但该值的目的是描述要做什么) 。我们编写这种描述动作的值的类型
IO()
。所以:I think I see what is going on.
declares that
reportReg
is a list of strings. But you wantreportReg
to be a function (marked in the type by->
) which takes a list of strings:Now the only question is what goes in place of the
???
-- what doesreportReg
return?This is where Haskell differs from every other language. It returns an I/O action. It is a function which maps lists of strings to actions -- namely, something to do rather than a value to return (so it does return value -- but that value's purpose is to describe what to do). We write the type of such action-describing values
IO ()
. So:其他人已经指出了您的错误原因,但我将评论您提出的其他问题:
是的,计算列表元素的简单方法是使用
length
函数。如果需要统计有多少个元素满足某个谓词,可以取过滤结果的长度。我不完全理解你的代码(例如,那个typ
参数在做什么?),但这里有一个例子(可能不完全相同):我建议的主要建议它从 do 块中提取尽可能多的代码(我上面的代码仍然可以在这方面进行改进)。尝试用纯代码完全解决您的问题,并仅使用 IO monad 来打印结果。
Other folks have pointed out the cause for your error, but I will comment on the other issue you've raised:
Yeah, the simple way to count the elements of a list is to use the
length
function. If you need to count how many elements satisfy a predicate, you can take the length of the result of filtering. I don't completely understand your code (e.g., what's thattyp
argument doing?), but here's an example (that probably doesn't do exactly the same):The main piece of advice I would suggest it to pull out as much code as possible from the do blocks (my code above still could use improvement in that regard). Try to solve your problem completely in terms of pure code, and use the IO monad only to print the result.