我尝试编写自定义函数,它接受一个数组并迭代它,我需要打印每个数字并递归启动相同的函数,但是我得到错误
在输入`main'时解析错误
码:
firstitem n = if n /= [] n firstitem( tail n ) main = do print(firstitem [1,2,3])I try to write custom function which take an array and iterate it, i need to print every digit and recursive launch the same function but i get error
parse error on input `main'
code:
firstitem n = if n /= [] n firstitem( tail n ) main = do print(firstitem [1,2,3])最满意答案
你的第一个问题是你的if语句的语法是错误的。 你应该写
firstItem n = if {- condition-} then {- do this -} else {- do that -}其次,还不清楚firstItem应该做的功能。 这听起来像是它应该返回列表的第一项,但是您的描述看起来好像您要遍历列表中的所有元素。
您可以将迭代和打印组合到一个单独的函数中,如下所示:
printAll xs = if null xs -- If the list is empty then return () -- then we're done, so we quit. else do print (head xs) -- Otherwise, print the first element printAll (tail xs) -- then print all the other elements. main = printAll [1,2,3]如果列表为空,则函数null返回True ,否则返回False 。 return ()语句可以被认为是“没有其他东西需要处理了,所以现在停止函数并返回结果”。 第三行和第四行包含一个“do block”。 do块基本上是一些printAll (tail xs) , printAll (tail xs)两个操作print (head xs)和printAll (tail xs)成一个动作。 你可以用大括号将它写得更清楚:
do { print (head xs); printAll (tail xs) }虽然你实际上并不需要它们 - 缩进指定你的意思。
这解决了你的问题,但它有点笨重。 毕竟Haskell应该是一门美丽的语言 - 所以我们让你的代码变得美丽! 最好使用模式匹配将列表拖入头部和尾部:
printAll [] = return () printAll (x:xs) = do print x printAll xs好多了。 但它可能更加模块化。 嘿,也许我们可以创建一个通用函数,将一个操作作为输入,并为列表中的每个元素执行该操作:
repeatedly f [] = return () repeatedly f (x:xs) = do f x repeatedly f xs printAll xs = repeatedly print xs那很整齐。 但实际上,已经有一个功能可以做到这一点。 它被称为mapM_ (它有一个很好的理由被称为这个,但我现在不会进入它),它在Control.Monad模块中:
import Control.Monad printAll xs = mapM_ print xs实际上,你可以放弃xs参数,编译器可以推断它应该在那里:
printAll = mapM_ print最后,你的代码很漂亮。 希望有点帮助。
Your first problem is that you have the wrong syntax for an if statement. You should write
firstItem n = if {- condition-} then {- do this -} else {- do that -}Second, it's not clear what the function firstItem is supposed to do. It sounds like it's supposed to return the first item of a list, but your description makes it seem as though you want to iterate over all elements of the list.
You can combine the iteration and printing into a single function like this:
printAll xs = if null xs -- If the list is empty then return () -- then we're done, so we quit. else do print (head xs) -- Otherwise, print the first element printAll (tail xs) -- then print all the other elements. main = printAll [1,2,3]The function null returns True if the list is empty, otherwise it returns False. The statement return () you can think of as saying "there's nothing more to process, so stop the function now and return no result". The third and fourth lines contain a "do block". The do block is basically a bit of glue that binds the two actions print (head xs) and printAll (tail xs) together into one action. You can write it with curly braces to make it a bit clearer:
do { print (head xs); printAll (tail xs) }although you don't actually need them - the indentation specifies what you mean.
This solves your problem, but it's a bit clunky. Haskell is supposed to be a beautiful language, after all - so let's make your code beautiful! It would be better to use pattern matching to pull the list apart into its head and tail:
printAll [] = return () printAll (x:xs) = do print x printAll xsThat's a lot better. But it could be more modular. Hey, maybe we could make a generic function that takes an action as input, and does that action for every element of the list:
repeatedly f [] = return () repeatedly f (x:xs) = do f x repeatedly f xs printAll xs = repeatedly print xsThat's neat. But actually, there's already a function that does this. It's called mapM_ (there is a good reason for it being called this, but I won't get into it now) and it's in the Control.Monad module:
import Control.Monad printAll xs = mapM_ print xsActually, you can leave off the xs argument, and the compiler can infer that it's supposed to be there:
printAll = mapM_ printFinally, your code is beautiful. Hope that helps a bit.
更多推荐
发布评论