Haskell Global var内部循环

时间:2017-11-27 13:58:11

标签: haskell

这是我的其中一项功能,涉及其他一些功能。

main' :: IO ()
main' = do putStr "Enter a string: "
           yx <- getLine
           let a = chunks yx
           let counter = (length . concat . map pairToList) a
           let c = 0
           let loop = do
               let b = a !! c
               let kk = xx b
               let c = c + 1
               let q = oncemore kk
               when (c /= (counter))  loop
           pp(q)

我的问题将以粗体显示在底部

我将在这里让剩下的其他功能期待以新的方式来解决我的问题。最后,我得到了最终输出应该如何的图像。 (我在底部重复上面的代码)

module Bigtext where
import Char
import Hugs.Prelude
import Data.List
import Control.Monad

cap :: Char -> Char
cap  c = if c >= 'a' && c <= 'z' then chr (ord c - 32) else c

letter' :: Char -> [String]

pp :: [String]->IO()
pp = putStr . concatMap (++"\n")

letter' 'A' = [" AA ",
               "A  A",
               "AAAA",
               "A  A",
               "A  A"]

letter' 'B' = ["BBB ",
               "B  B",
               "BBB ",
               "B  B",
               "BBB "]

letter' 'C' = [" CCC",
               "C   ",
               "C   ",
               "C   ",
               " CCC"]

letter' 'D' = ["DDD ",
               "D  D",
               "D  D",
               "D  D",
               "DDD "]

letter' 'E' = ["EEEE",
               "E   ",
               "EEE ",
               "E   ",
               "EEEE"]

letter' 'F' = ["FFFF", 
               "F   ", 
               "FFF ", 
               "F   ", 
               "F   "]

letter' 'G' = [" GGG ", 
               "G    ", 
               "G  GG", 
               "G   G", 
               " GGG "]

letter' 'H' = ["H  H", 
               "H  H", 
               "HHHH", 
               "H  H", 
               "H  H"]

letter' 'I' = ["III", 
               " I ", 
               " I ", 
               " I ", 
               "III"]

letter' 'J' = ["    J", 
               "    J", 
               "    J", 
               "J   J", 
               " JJJ "]

letter' 'K' = ["K  K", 
               "K K ", 
               "KK  ", 
               "K K ", 
               "K  K"]

letter' 'L' = ["L   ",
               "L   ",
               "L   ",
               "L   ",
               "LLLL"]

letter' 'M' = ["M   M",
               "MM MM",
               "M M M",
               "M   M",
               "M   M"]

letter' 'N' = ["N   N",
               "NN  N",
               "N N N",
               "N  NN",
               "N   N"]

letter' 'O' = [" OOO ",
               "O   O",
               "O   O",
               "O   O",
               " OOO "]

letter' 'P' = ["PPPP ",
               "P   P",
               "PPPP ",
               "P    ",
               "P    "]

letter' 'Q' = [" QQQ  ",
               "Q   Q ",
               "Q   Q ",
               "Q  QQ ",
               " QQQQQ"]

letter' 'R' = ["RRRR ",
               "R   R",
               "RRRR ",
               "R R  ",
               "R  RR"]

letter' 'S' = [" SSS ",
               "S    ",
               " SSS ",
               "    S",
               "SSSS "]

letter' 'T' = ["TTTTTT",
               "  TT  ",
               "  TT  ",
               "  TT  ",
               "  TT  "]

letter' 'U' = ["U   U",
               "U   U",
               "U   U",
               "U   U",
               " UUU "]

letter' 'V' = ["V     V",
               "V     V",
               " V   V ",
               "  V V  ",
               "   V   "]

letter' 'W' = ["W     W",
               "W     W",
               "W  W  W",
               " W W W ",
               "  W W  "]

letter' 'X' = ["X   X",
               " X X ",
               "  X  ",
               " X X ",
               "X   X"]

letter' 'Y' = ["Y   Y",
               " Y Y ",
               "  Y  ",
               "  Y  ",
               "  Y  "]

letter' 'Z' = ["ZZZZZ",
               "   Z ",
               "  Z  ",
               " Z   ",
               "ZZZZZ"]

letter' ' ' = ["      ",
               "      ",
               "      ",
               "      ",
               "      "]

letter' c = letter' (cap c)

letter :: Char -> IO()
letter c = pp(letter' (cap c))

zipAll :: [[String]] -> [String]
zipAll = map unwords . transpose

chunk :: Int -> [a] -> [[a]]
chunk _ [] = []
chunk n xs = first : chunk n rest where (first, rest) = splitAt n xs

splitSkip :: Int -> [a] -> [[a]]
splitSkip n xs = transpose $ chunk n xs

chunks yx = words yx

pairToList :: a -> [a]
pairToList x = [x]

xx b = zipAll (map (letter' . head) (splitSkip (length b) b))

type MyString = [String]

oncemore :: MyString -> MyString
oncemore kk = kk ++ kk

main' :: IO ()
main' = do putStr "Enter a string: "
           yx <- getLine
           let a = chunks yx
           let counter = (length . concat . map pairToList) a
           let c = 0
           let loop = do
               let b = a !! c
               let kk = xx b
               let c = c + 1
               let q = oncemore kk
               when (c /= (counter))  loop
           pp(q)

这是预期的输出:

expected output

这就是我目前所处的位置

main' :: IO ()
main' = do putStr "Enter a string: "
           yx <- getLine
           let a = chunks yx
           let counter = (length . concat . map pairToList) a
           let c = 0
           let loop c = do
               let c' = c + 1
               let b = a !! (c'-1)
               let kk = xx b
               if c' /= counter
                  then return kk
               else loop c'
           **kk <- loop c**
           pp(kk)

kk&lt; - loop c 行中,如果我为一个数字更改c,可能会得到一个单词(取决于您输入的单词数),问题是:如何打印所有索引?例如,如果我有3个单词,如何在没有硬编码的情况下将其打印出来?

抱歉我的英文... 谢谢你的时间。

1 个答案:

答案 0 :(得分:4)

Haskell变量在程序员通常解释单词的意义上并非“可变”,即它们不可变。基本上,任何Haskell变量都只是一个局部常量。因此,你的循环结构没有意义,即

       let c = 0
       let loop = do
            ...
            let c = c + 1
            when (c /= counter) loop

根本不起作用。

  • 你实际上并没有进入循环,只是定义了循环的内容。
  • 如果您确实进入了循环,那么您将错过let c = c + 1。这不会修改现有的c,而是只定义一个完全独立的变量c,因为它在较窄的范围内,阴影c = 0。这个阴影绑定甚至在定义本身中使用,即计算c运行时需要知道c的值,它需要计算c,...等等。

你真正想要的是

       let c = 0
       let loop c = do
            ...
            let c' = c + 1
            when (c' /= counter) $ loop c'
       loop 0  -- actually invoke the loop, starting from 0.

但即便如此,这个循环并没有真正完成任何事情 - 你只是在每次迭代中定义一些局部变量,但实际上从来没有对它们产生持久影响。

可以在每次迭代中提交一些实际的IO动作,例如打印出一个大字母。你也可以从循环中得到一些结果,这似乎是你在这个问题中提出的问题。例如,要将q的最后一个“状态”广播到外部,您需要替换when(如果条件未满足,则为return ()的快捷方式)< / p>

       let loop c = do
            let q = ...
            let c' = c + 1
            if c' == counter
             then return q
             then loop c'
       q <- loop 0

但我认为这是明智的;相反,一个更好的方法是连接仍然以列表形式的所有字母(不需要任何丑陋的索引/长度杂耍,也不需要任何IO或显式循环,仅mapconcat),以及然后将整个结果打印成一个干净的putStr