我有这个函数接收一个整数列表,应该返回一个String
generateSTR :: [Int] -> String
generateSTR ([]) = ""
generateSTR (x) = daux (x (maximum x) x "")
where daux ((x:xs) mh y:ys strdib)
| mh == 0 = daux xs mh ys (strdib ++ "-")
| mh <= h = daux (xs mh ys (strdib ++ "*"))
| mh > h = daux (xs mh ys (strdib ++ " "))
| mh == 0 && length(lh) == 0 = daux xs (mh-1) ys (strdib ++ "\n")
daux ([] mh lh strdib) = strdib
问题是我收到了错误:
"Parse error in pattern: (x : xs)"
但是我看不出我做错了什么。
肯定这是一个愚蠢的错误,但我是HASKELL的新手,我想我会发疯!。
答案 0 :(得分:2)
由于外括号,这一行:
where daux ((x:xs) mh y:ys strdib)
说daux需要一个参数。也许你的意思是:
where daux (x:xs) mh (y:ys) strdib
表示它需要四个参数。请注意在y:ys
附近添加的parens。
您还必须修改主函数中daux
的调用位置,例如:
generateSTR (x) = daux (x (maximum x) x "")
^ ^ - remove these
答案 1 :(得分:2)
这个Haskell语法f x y z
不只是其他语言写成f(x,y,z)
的不同语法。它等同于,是的,但只是在某种意义上它也等同于f(z,y,x)
:你仍然需要做出区分。
Haskell函数通常写为curried。这意味着,如果f
“接受三个参数”,它实际上做的是接受一个参数,然后是另一个参数,然后是另一个参数:
f x y z ≡ ((f x) y) z
换句话说,f
是一个函数,其结果是一个函数,其结果是一个函数。只有第三个函数的结果才是“最终结果”。因此,你显然不能写它f (x y z)
- 这将是完全不同的东西,即f
应用于将函数x
应用于{的结果{1}}和y
。
也许所有这些听起来都很复杂,但是你会发现很多情况下,currying允许你编写非常简洁和强大的代码,否则你只需要担心它......只需写下没有括号的内容即可实际上是组独立的子表达式!
应用于您的示例 - 这是编写它的正确方法:
z
如果你还没有遇到过$
运算符:它与将它的两边放在括号中的效果相同,即
generateSTR :: [Int] -> String
generateSTR [] = ""
generateSTR x = daux x (maximum x) x ""
where daux (x:xs) mh y:ys strdib
| mh == 0 = daux xs mh ys $ strdib ++ "-"
| mh <= h = daux xs mh ys $ strdib ++ "*"
| mh > h = daux xs mh ys $ strdib ++ " "
| mh == 0 && length lh == 0 -- note: this actually doesn't work, `lh` is not in scope here.
= daux xs (mh-1) ys $ strdib ++ "\n"
daux [] mh lh strdib = strdib
...正如我所说, daux xs mh ys $ strdib ++ "-"
≡ (daux xs mh ys) (strdib ++ "-")
实际上与(f x y z) w
相同,所以在这种情况下它与f x y z w
相同。但与daux xs mh ys (strdib ++ "-")
不同,后者意味着您将函数daux (xs mh ys (strdib ++ "-"))
应用于xs
,然后mh
等,这当然不起作用,因为{{ 1}}是一个列表!