【问题标题】:Haskell How to compare IO tuple with normal tupleHaskell 如何比较 IO 元组和普通元组
【发布时间】:2019-06-15 14:58:51
【问题描述】:

我尝试将 IO 元组的元组成员(日期)与普通元组进行比较。

d1 ->(Integer, Int, Int)d2 -> IO (Integer, Int, Int),

可以比较这两个元组吗? 我尝试过类似的方法:

import Data.Time.Clock
import Data.Time.Calendar
import Data.Time.LocalTime

-- helper functions for tuples
x_fst (x,_,_) = x
x_snd (_,x,_) = x
x_trd (_,_,x) = x

getDate :: IO (Integer, Int, Int)
getDate = do
    now <- getCurrentTime
    tiz <- getCurrentTimeZone
    let zoneNow = utcToLocalTime tiz now
    let date@(year, month, day) = toGeorgian $ localDay zoneNow
    return $ date -- here I will return an IO tuple -> IO (Integer, Int, Int)

compareDates :: a -> IO (Integer, Int, Int) -> IO Bool
compareDates d1 d2 = do
    let year1 = x_fst d1
    let year2 = x_fst d2
    let month1 = x_snd d1
    let month2 = x_snd d2
    let day1 = x_trd d1
    let day2 = x_trd d2
    return $ (year1 == year2 && month1 == month2 && day1 == day2)

但我收到消息,我无法将 IO 元组与普通元组进行比较:

Couldn't match expected type `(Integer, Integer, Integer)` 
  with actual type `IO (Integer, Int, Int)`
  In the second argument of `compareDates`, namely `date`

有办法解决吗?我将不胜感激任何帮助。

谢谢。

【问题讨论】:

标签: date haskell io io-monad do-notation


【解决方案1】:

在评论/聊天部分的帮助下,我可以使用以下代码:

getDate :: IO Day
getDate = do
    now <- getCurrentTime
    tz <- getCurrentTimeZone
    return . localDay $ utcToLocalTime tz now

main = do
    d2 <- getDate
    return $ fromGregorian 2019 6 15 == d2

【讨论】:

  • 值得注意的是,compareDates 实际上只是(自动生成的)三元组的Eq 实例,因此它可以缩短为compareDates = (==)
  • 或更少依赖于预定义的 Eq 元组实例 compareDates (y1, m1, d1) (y2, m2, d2) = y1 == y2 &amp;&amp; m1 == m2 &amp;&amp; d1 == d2
  • compareDates 中当然不需要do;一个适当的let 表达式就足够了。 let { year1 = xx_fst d2; year2 = xx_fst d2; ... } in year1 == year2 &amp;&amp; month1 == month2 &amp;&amp; day1 == day2.
  • main 的最后一行应该是return (compareDates d1 d2);无需再次调用getDate&gt;&gt;=,这会隐藏第一次调用getDate 读取的值。
  • 我冒昧地简化了您的代码。除了前面 cmets 中已经列出的改进之外,当 Days 已经有一个非常合适的比较可用时,无需将 Day 解构为元组并比较元组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
相关资源
最近更新 更多