haskell - Haskell 标志模式
问题描述
我是 Haskell 的一个非常新的用户,并且在一些工作中陷入了困境。我被分配了制作一个标志模式函数的任务,它会产生这样的东西 -
这是一个链接到它应该是什么样子的图像 来描述它,它基本上是一个空心矩形,中间有一个 X 用 * 产生
唯一的问题是我不太清楚如何几乎完全使用haskell,尤其是坐标甚至if-then-else。
这是我到目前为止所拥有的,我几乎被困在 if then else 部分。任何帮助将非常感激!
flagpattern :: Int -> String
flagpattern a
| a <= 4 = ""
| otherwise = fill (grid a) a
grid :: Int -> [(Int, Int)]
grid a = [(x, y)| x<- [0..a], y<-[0..a]]
fill :: [(Int, Int)] -> Int -> String
fill [(x:xs,y:ys)] a
if fst (x,y) == 0 then
if snd (x,y) < a then "*" ++ fill [(xs,ys)]
else "*\n" ++ fill [(xs,ys)]
else
if fst (x,y) == a then
if snd (x,y) < a then "*" ++ fill [(xs,ys)]
else "*\n" ++ fill [(xs,ys)]
else
if fst (x,y) + snd (x,y) == a then
if fst (x,y) == a then "*\n" ++ fill [(xs,ys)]
else "*" ++ fill [(xs,ys)]
else " " ++ fill [(xs,ys)]
解决方案
我在您发布的代码中看到的主要问题是缺少=
定义fill
和错误缩进的正文。修复:
fill :: [(Int, Int)] -> Int -> String
fill [(x:xs,y:ys)] a = -- NOTE: need an `=` here
-- NOTE: function body needs to be indendented
if fst (x,y) == 0 then
if snd (x,y) < a then "*" ++ fill [(xs,ys)]
else "*\n" ++ fill [(xs,ys)]
else
if fst (x,y) == a then
if snd (x,y) < a then "*" ++ fill [(xs,ys)]
else "*\n" ++ fill [(xs,ys)]
else
if fst (x,y) + snd (x,y) == a then
if fst (x,y) == a then "*\n" ++ fill [(xs,ys)]
else "*" ++ fill [(xs,ys)]
else " " ++ fill [(xs,ys)]
摆脱了解析错误并引入了大约十亿个类型错误。在您的定义中fill
:
fill [(x:xs,y:ys)] a = ...
第一个参数模式不是匹配元组列表的正确方法:
[(0,0),(0,1),...]
相反,您想像这样从其余元组中剥离第一个元组:
fill ((x,y):rest) a = ...
并传递rest
给递归fill
调用。我认为,您还忘记了将第二个参数传递a
给递归fill
调用。修复该问题后,您的函数如下所示:
fill :: [(Int, Int)] -> Int -> String
fill ((x,y):rest) a =
if fst (x,y) == 0 then
if snd (x,y) < a then "*" ++ fill rest a
else "*\n" ++ fill rest a
else
if fst (x,y) == a then
if snd (x,y) < a then "*" ++ fill rest a
else "*\n" ++ fill rest a
else
if fst (x,y) + snd (x,y) == a then
if fst (x,y) == a then "*\n" ++ fill rest a
else "*" ++ fill rest a
else " " ++ fill rest a
这种类型的检查,虽然flagpattern 7
在输出一些不正确的输出后以不匹配的模式崩溃:
> flagpattern 7
"********\n * * * * * * ********\n*** Exception: Flag.hs:(19,1)-(31,33): Non-exhaustive patterns in function fill
但也许这会帮助你继续工作。
另外,请注意在 Haskell 中,表达式[0..a]
包括两个端点:
> [0..7]
[0,1,2,3,4,5,6,7]
因此,如果您希望返回 7x7 网格而不是 8x8 网格,您可能希望使用其中一个[0..a-1]
或[1..a]
ingrid
对测试进行相应的更改。fill
flagPattern 7
推荐阅读
- java - 将 JSON 文件中的日期值读入 Java HashMap
- python - Glob 在网络位置上递归失败?
- r - 如何将表达式传递给ggplot中的geom_text标签?(继续)
- r - 两个字符组之间交替模式的正则表达式
- java - 嵌入式码头 9 不适用于 @Webservlet
- html - Bootstrap 4 使用对前景 img 没有响应
- python - 在 numpy 的 if 语句中使用 i 进行迭代
- javascript - 如何使用 nodejs 启动服务器?
- regex - 正则表达式可选组选择不起作用
- html - 如何在网站上使用两个背景图片。一个将在另一个前面 - 前面的稍微小一点