在haskell中生成给定月份和年份的日历

在haskell中生成给定月份和年份的日历,haskell,functional-programming,Haskell,Functional Programming,我从一周开始学习haskell,现在面临着不同的问题。这一次,我必须根据给定的月份和年份创建日历。我几乎完成了,但问题是我不能从开始的那一天开始填满时间 我的解决办法是 getDaysInMonth year month=(nDays,sDay) where nDays = gregorianMonthLength year month sDay= digitToInt(last

我从一周开始学习haskell,现在面临着不同的问题。这一次,我必须根据给定的月份和年份创建日历。我几乎完成了,但问题是我不能从开始的那一天开始填满时间

我的解决办法是

getDaysInMonth year month=(nDays,sDay) 
                          where nDays = gregorianMonthLength year month
                                sDay= digitToInt(last(showWeekDate (fromGregorian year month 01)))
year=2013
month=10
months=["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"]
mnth=months!!(month-1)
monthDate = getDaysInMonth year month
startAt=snd(monthDate)
totalDays = fst(monthDate)
printLine = "\n"++concat ["+---\t" | r <- [1..7]]
check x | x>totalDays=""
        | x<=totalDays=show x
genDays n m="\n "++concat[check(x)++"\t|"|x<-[n..m]]
genD 6=""
genD sP=genDays ((sP-1)*7+1) (sP*7) ++genD (sP+1)
generateCalendar=printLine++"\n "++
                        concat [[r]++"\t|" | r <- mnth]++printLine++
                        "\n Sun\t|Mon\t|Tue\t|Wed\t|Thu\t|Fri\t|Sat"++printLine++
                        genD 1
main=do
     putStrLn generateCalendar

所以问题是十月应该从周一开始。我认为解决方案的实施有点混乱,但我如何解决这个问题

提前感谢

解决此问题的更“实用”的方法是:

cells = [ "", "", "", "1", "2", "3", ..., "31", "", "" ]
  • 创建一个包含35个字符串的列表,每个字符串要么是空字符串,要么是一个(字符串化的)数字
  • 将列表分成7个元素的块(这样你就得到5个块)
  • 对于每个区块,将元素渲染为日历中的一行
  • 例如,2013年10月,35个字符串的列表为:

    cells = [ "", "", "", "1", "2", "3", ..., "31", "", "" ]
    
    可以使用以下帮助函数创建块:

    chunksOf7 (a:b:c:d:e:f:g:rest) = [ [a,b,c,d,e,f,g] ] ++ chunksOf7 rest
    chunksOf7 xs = xs
    
    (有更好的方法来定义
    块7
    ,但这就足够了。)

    要渲染块,请执行以下操作:

    renderChunk cells =  (concat $ map renderCell cells) ++ "\n"
    renderCell c = pad 3 c ++ "|"
    pad n str = str ++ (replicate (n-(length str)) ' ')
    
    pad n str
    在字符串
    str
    的右侧填充空格,直到总长度为
    n
    replicate n a
    创建一个值为
    a
    重复
    n
    次的列表

    并将其放在一起(一旦有了
    单元格
    列表):

    现在,给定一年零一个月,您只需编写一个函数来定义什么是
    单元格。
    单元格列表将包括:

    • 一些前导空字符串
    • 然后是1到30(或31或该月的最后一天)
    • 后跟一些尾随的空字符串
    i、 e:

    cellsForYearAndMonth y y m=(复制n1“”)
    
    ++[show d | d谢谢@user5402。我终于得到了工作版本

    import Data.Time.Calendar
    import Data.Time.Calendar.WeekDate
    import Data.Char
    year=2014
    month=2
    months=["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"]
    mnth=months!!(month-1)
    monthDate = getDaysInMonth year month
    startAt=snd(monthDate)
    totalDays = fst(monthDate)
    
    getDaysInMonth year month=(nDays,sDay) 
                          where nDays = gregorianMonthLength year month
                                sDay= digitToInt(last(showWeekDate (fromGregorian year month 01)))
    cells = (replicate n1 "")
                              ++ [ show d | d <- [1..lastday] ]
                              ++ (replicate n2 "")
              where lastday = totalDays
                    n1=(startAt-1)
                    n2=(7-(totalDays-(29-startAt)))
    chunksOf7 []=[]
    chunksOf7 (a:b:c:d:e:f:g:rest) = [ [a,b,c,d,e,f,g] ] ++ chunksOf7 rest
    
    pad n str = str ++ (replicate (n-(length str)) ' ')
    renderCell c = pad 3 c ++ "|"
    renderChunk cells =  (concat $ map renderCell cells) ++ "\n"
    
    printLine = "\n"++concat ["+---" | r <- [1..7]]++"\n"
    monthLine=concat [[r]++" |" | r <- mnth]
    dayLine="Sun|Mon|Tue|Wed|Thu|Fri|Sat"
    heading=concat[printLine,"Year: ",show year,printLine,monthLine,printLine,dayLine,printLine]
    
    renderCalendarBody cells =  heading++concat (map renderChunk chunks)
      where chunks = chunksOf7 cells
    
    main= do putStrLn $ renderCalendarBody cells
    
    导入Data.Time.Calendar
    导入Data.Time.Calendar.WeekDate
    导入数据.Char
    年份=2014年
    月份=2
    月份=[“一月”、“二月”、“三月”、“四月”、“五月”、“六月”、“七月”、“八月”、“九月”、“十月”、“十一月”、“十二月”]
    mnth=月份!!(第1个月)
    monthDate=getDaysInMonth年月份
    startAt=snd(月日)
    totalDays=fst(月日)
    getDaysInMonth年月=(星期日,星期四)
    式中,nDays=gregorianMonthLength年-月
    sDay=数字点(最后一个(显示工作日(从公历年第01个月开始)))
    细胞=(复制n1“”)
    
    ++[show d | d“我认为解决方案的实现有点[混乱]”-然后清理它!有什么理由不能在几个月和几天内使用自定义
    数据类型吗?不使用字符串会更干净、更安全。2013年10月从周二开始。
    
    cellsForYearAndMonth y m = (replicate n1 "")
                                  ++ [ show d | d <- [1..lastday] ]
                                  ++ (replicate n2 "")
      where lastday = ...
            n1 = ... number of leading empty strings ...
            n2 = ... number of trailing empty strings ...
    
    import Data.Time.Calendar
    import Data.Time.Calendar.WeekDate
    import Data.Char
    year=2014
    month=2
    months=["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"]
    mnth=months!!(month-1)
    monthDate = getDaysInMonth year month
    startAt=snd(monthDate)
    totalDays = fst(monthDate)
    
    getDaysInMonth year month=(nDays,sDay) 
                          where nDays = gregorianMonthLength year month
                                sDay= digitToInt(last(showWeekDate (fromGregorian year month 01)))
    cells = (replicate n1 "")
                              ++ [ show d | d <- [1..lastday] ]
                              ++ (replicate n2 "")
              where lastday = totalDays
                    n1=(startAt-1)
                    n2=(7-(totalDays-(29-startAt)))
    chunksOf7 []=[]
    chunksOf7 (a:b:c:d:e:f:g:rest) = [ [a,b,c,d,e,f,g] ] ++ chunksOf7 rest
    
    pad n str = str ++ (replicate (n-(length str)) ' ')
    renderCell c = pad 3 c ++ "|"
    renderChunk cells =  (concat $ map renderCell cells) ++ "\n"
    
    printLine = "\n"++concat ["+---" | r <- [1..7]]++"\n"
    monthLine=concat [[r]++" |" | r <- mnth]
    dayLine="Sun|Mon|Tue|Wed|Thu|Fri|Sat"
    heading=concat[printLine,"Year: ",show year,printLine,monthLine,printLine,dayLine,printLine]
    
    renderCalendarBody cells =  heading++concat (map renderChunk chunks)
      where chunks = chunksOf7 cells
    
    main= do putStrLn $ renderCalendarBody cells