如何在Haskell中将IO()更改为[String]?

时间:2016-11-20 03:45:13

标签: haskell

我正在制作一个在字符周围打印字符框的框架,如下所示。

这是框架的示例。示例了解我的实际帧是什么以及我想要的所有这些功能正确,左,上,下:

aA的字符串列表。

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:[]

2 个答案:

答案 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建议的内容。但是,既然你问这个问题,我相信你已经考虑过了,并且不知怎的,这不是一个选择。