所以我在haskell中有一个数据类型,定义如下:
import qualified Data.UUID as UUID
import qualified Data.Time.Clock as CLK
data MyRecord = MyRecord {
id :: UUID.UUID,
creationDate :: CLK.UTCTime,
comment :: String
}
现在的问题是UUID和UTCTime是在IO monad中返回的。我用来生成它们的函数具有以下类型
用于UUID
nextRandom :: IO uuid-types-1.0.3:Data.UUID.Types.Internal.UUID
获取当前时间戳记:
getCurrentTime :: IO UTCTime
我的问题是如何使用数据构造函数实际初始化数据类型?
我可以执行以下操作
MyRecord <$> nextRandom
这可行,但是我不明白如何为构造函数提供其他参数。
答案 0 :(得分:3)
您可以为此使用顺序应用程序 (<*>) :: Applicative f => f (a -> b) -> f a -> f b
。例如:
MyRecord <$> nextRandom <*> getCurrentTime <*> return "some comment"
这等效于:
some_function :: IO MyRecord
some_function = do
r <- nextRandom
t <- getCurrentTime
return (MyRecord r t "some comment")
这基本上发生的是,如果您写:
MyRecord <$> nextRandom
您构造一个IO (UTCTime -> String -> MyRecord)
类型的项目。现在,通过将(<*>)
函数与该函数一起用作左操作数,并将IO UTCTime
作为右操作数,我们就可以构造一个IO (String -> MyRecord)
类型的对象。
我们可以使用return :: Monad m => a -> m a
或pure :: Applicative f => a -> f a
将String
转换为IO String
,因此我们再次使用(<*>)
将其应用于部分数据构造函数。
答案 1 :(得分:2)
这是常见的applicative style pattern:
MyRecord <$> nextRandom
<*> getCurrentTime
<*> pure "my comment"