我正在制作一个在字符周围打印字符框的框架,如下所示。
这是框架的示例。示例了解我的实际帧是什么以及我想要的所有这些功能正确,左,上,下:
a
是A
的字符串列表。
Main> showMatDownAttach '@' a
aaaaa
a a
a a
aaaaaaa
a a
a a
a a
@@@@@@@@@
Main> showMatDownAttach '@' a
aaaaa
a a
a a
aaaaaaa
a a
a a
a a
@@@@@@@@@
我也有左右。现在我想创建一个可以在一个函数中组合所有这些函数的函数。我怎么能这样做?
a = [" aaaaa "," a a "," a a "," aaaaaaa "," a a "," a a "," a a "]
--badar = putStr( concat (map (++ "\n")(letter 'a')))
--showMat :: Char -> IO()
--showMat ch = putStr (concat ( map(++ "\n") (letter 'a')))
replicateIt :: Int -> [Char] -> [Char]
replicateIt x ls=take x (cycle ls)
--repeatIt :: Int -> [Char] -> [[Char]]
repeatIt num []=[]
repeatIt num (x:sx)= replicateIt num [x]:(repeatIt num sx)
hStretchChar :: Int -> Char -> String
hStretchChar i ch = replicate i ch
hStretchString :: Int -> String -> String
hStretchString i sts = concat ( map ( hStretchChar i) sts)
hStretchListOfString :: Int -> [String] -> [String]
hStretchListOfString i stlist = map (hStretchString i ) stlist
vStretchString :: Int -> String -> String
vStretchString i str = concat (replicate i (str ++ "\n"))
vStretchListOfString :: Int -> [String] -> [String]
vStretchListOfString i strList = map (vStretchString i) strList
stretch :: Int -> Int -> [String] -> [String]
stretch i j strList = vStretchListOfString i (hStretchListOfString j strList)
showMat' :: [String] -> IO()
showMat' strList = putStr (concat (stretch 1 1 strList))
--Left Attach Character
leftattach :: Char -> [String] -> [String]
leftattach a strlist = map ( a: ) strlist
showMatCharAttachLeft :: Char -> [String] -> IO()
showMatCharAttachLeft a strList = putStr (concat (stretch 1 1 ( leftattach a strList)))
charToString :: Char -> String
charToString a = a:[]
--Right Attach Character
rightattach :: Char -> [String] -> [String]
rightattach a strlist = map (++(charToString a)) strlist
showMatCharAttachRight :: Char -> [String] -> IO()
showMatCharAttachRight a strList = putStr (concat (stretch 1 1 ( rightattach a strList)))
--Up Attach Character
upattach :: Char -> [String] -> [String]
upattach a strList = take (length (head strList)) (cycle (charToString a)) : strList
showMatUpAttach :: Char -> [String] -> IO()
showMatUpAttach a strList = putStr (concat (stretch 1 1 (upattach a strList)))
--Down Attach Character
downattach :: Char -> [String] -> [String]
downattach a strList = strList ++ listOfCharTolistOfString (take (length (head strList)) (cycle (charToString a)))
showMatDownAttach :: Char -> [String] -> IO()
showMatDownAttach a strList = putStr (concat (stretch 1 1 (downattach a strList)))
--test0 a strList = listOfCharTolistOfString (take (length (head strList)) (cycle (charToString a)))
listOfCharTolistOfString :: [Char] -> [String]
listOfCharTolistOfString a = a:[]
答案 0 :(得分:1)
IO ()
是一种非常不透明的类型;你用它做的事情并不多,而且没有任何有意义的方法可以将它转换为[String]
。一旦你进入IO
,你就无法摆脱它。
通常在Haskell中,您可以在不使用IO
的情况下编写大部分代码。这是解决问题的方法,以证明我的意思。请注意所有"帧"代码是使用纯函数定义的,IO
在最后main
之前不会被引入。
import Data.Foldable (traverse_)
import Data.List (repeat)
frame1 :: a -> [a] -> [a]
frame1 f xs = [f] ++ xs ++ [f]
frame2 :: a -> [[a]] -> [[a]]
frame2 f grid = frame1 edge $ frame1 f <$> grid
where edge = take (width grid + 2) $ repeat f
width :: [[a]] -> Int
width [] = 0
width (x:_) = length x
a :: [[Char]]
a = [ " aaaaa "
, " a a "
, " a a "
, " aaaaaaa "
, " a a "
, " a a "
, " a a "
]
main :: IO ()
main = traverse_ putStrLn $ foldr frame2 a "* &"
输出:
***************
* *
* &&&&&&&&&&& *
* & aaaaa & *
* & a a & *
* & a a & *
* & aaaaaaa & *
* & a a & *
* & a a & *
* & a a & *
* &&&&&&&&&&& *
* *
***************
答案 1 :(得分:0)
因此,IO ()
封装了所有副作用,而不仅仅是控制台输出。如此迂腐无法将IO ()
更改为[String]
&#34;
话虽如此,我相信System.Posix.Redirect
正是您所寻找的。您只想致电showMatDownAttach
以捕获stdout
以获得您想要的[String]
。
快速谷歌搜索显示还有更多的软件包:
现在这样做并不是非常惯用的Haskell,如果你有showMatDownAttach
的访问权限,你会想要将其更改为https://stackoverflow.com/a/40701235/111021建议的内容。但是,既然你问这个问题,我相信你已经考虑过了,并且不知怎的,这不是一个选择。