haskell - 是否可以将嵌套列表返回为 IO()
问题描述
我有一些简单的函数,我需要 makeMove 来返回 IO():
toPole :: Show a => [a] -> [a] -> String
toPole fpole spole = show(head fpole:spole)
fromPole :: Show a => [a] -> String
fromPole fpole = show (tail fpole)
makeMove :: [a] -> [a] -> IO ()
makeMove [] _ = return ()
makeMove fpole spole = putStr (unwords p)
where p = [fromPole fpole, toPole fpole spole]
这个想法是我有两个列表,我想将列表的第一项移动fpole
到第二个列表spole
,并将它们打印为嵌套列表[[],[]]
。putStr
有没有办法做到这一点?我用 and 的返回类型尝试了不同的东西toPole
,fromPole
但认为如果返回类型是 . 将 makeMove 转换为 IO() 会更容易String
。
我得到的错误来自fromPole fpole
于where p = [fromPole fpole, ...
:
No instance for (Show a) arising from a use of ‘fromPole’
解决方案
makeMove
也需要Show a
约束。就目前而言,您是说makeMove
可以接受任何类型的列表作为参数,但随后您尝试将那些可能Show
较少的值传递给fromPole
.
makeMove :: Show a => [a] -> [a] -> IO ()
makeMove [] _ = return ()
makeMove fpole spole = putStr (unwords p)
where p = [fromPole fpole, toPole fpole spole]
更简洁的实现不会对列表元素进行任何假设toPole
或做出任何假设;fromPole
事实上,它们几乎没有必要。没有它们,您可以定义makeMove
(可以说更清楚)。
transfer :: [a] -> [a] -> ([a], [a])
transfer (x:xs) ys = (xs, (x:ys))
makeMove :: Show a => [a] -> [a] -> String
makeMove fpole spole = let (fpole', spole') = transfer fpole spole
in unwords [fpole', spole']
showMove :: Show a => [a] -> [a] -> IO ()
showMove fpole spole = print (makeMove fpole spole)
在这里,我将函数分解为三个逻辑部分:
transfer
只需将元素从一个极点移动到另一个极点。makeMove
String
从结果中创建一个transfer
showMove
输出移动的结果。
尽可能多的工作保存在纯函数中,只showMove
对IO
.
推荐阅读
- docker - 关于网络接口的 Ansible 未定义事实
- java - 计算递归方法的时间复杂度
- c++ - 选择选举获胜者的程序
- r - 如何使用 ggplot2 将标准错误添加到 nls 图?
- ansible - 如何在 Ansible 中检查某个状态码 (4xx)?
- python - Python - 替换列表中的特定数字
- javascript - 无法将json数据获取到jquery数据表
- javascript - 如何在 element 的 slideUp() 之前阻止滚动和 body 的高度,并在新元素的 slideDown() 之后删除 css?- jQuery
- excel - VBA Shell()、WSrcipt.Shell 和 Shell.Application。我还能尝试什么?
- python-3.x - 如何在 AWS AMI Linux Lambda 中设置语言环境?