[英]writing my own log data type haskell
我是Haskell的新手,我正在編寫一個程序,該程序中希望有一條帶有創建時間的日志消息,並有可能將文本附加到當前msg,以便僅更改消息,但時間會保留創建時間。 我嘗試執行以下操作:
data Msg = MNothing | MJust UTCTime String
M
用於消息,而進行M
MNothing
的原因是,因此有可能出現空消息。
我還寫道:
instance Monoid Msg where
mempty = MNothing
(MJust t s) `mappend` (MJust t' s') = MJust (minimum (t,t')) (s++s')
這樣,我可以將mappend
用於兩條消息,這將花費消息中最早的時間。
我的問題是:
對於Msg類型,我在創建MJust
變量時遇到了麻煩,原因是調用getCurrentTime
返回IO UTCTime
,而我想擁有UTCTime
。 我該如何解決?
我只能concat
兩個Msg
,但是這樣做是沒有意義的,是否可以使用普通的String
(或[Char]
)來合並Msg
?
我是Haskell的新手,所以也許我想念什么? 謝謝。
對於Msg類型,我很難創建一個MJust變量,原因是調用getCurrentTime返回IO UTCTime,而我想擁有UTCTime。 我該如何解決?
IO
有許多功能可以幫助解決這些“不匹配”(它們比較通用,也可以用於其他類型,但是現在我們不關心這些功能)。
重要的思想是您不要從IO
提取值。 取而代之的是,您“提升”功能以在 IO
內部工作!
例如, fmap
函數(也稱為liftA
)將轉換一個函數,使其在IO
內部運行:
fmap :: (a -> b) -> IO a -> IO b
liftA2
讓我們將兩個參數函數應用於IO
內部的參數:
liftA2 :: (a -> b -> c) -> IO a -> IO b -> IO c
return
(也稱為pure
)使您可以將任何值放入IO
:
return :: a -> IO a
在您的情況下,您可以像這樣創建IO Msg
類型的值
liftA2 MJust getCurrentTime (pure "somestring")
記住,您不會讓IO
失去UTCTime
。 相反,您將所需的一切都帶入IO
。
還存在更靈活的函數/運算符(>>=)
(稱為“綁定”),可用於構建復合IO
操作,其中第二個操作取決於第一個操作返回的值:
(>>=) :: IO a -> (a -> IO b) -> IO b
請注意,我們可以決定什么IO b
基礎上的結果來進行IO a
。
一個簡單的例子:
getLine >>= \msg -> if msg == "foo" then putStr "yay" else putStr "nay"
再次是IO Msg
:
getCurrentTime >>= \theTime -> pure (MJust theTime "foo")
使用(>>=)
我們可以構造與命令式語言中的語句塊非常相似的操作序列。 但是寫所有這些(>>=)
可能會引起廣泛的麻煩,因此有一種語法語法糖(稱為do-notation)使事情變得更容易。
表示形式的IO Msg
:
do theTime <- getCurrentTime
pure (MJust theTime "foo")
在這里<-
不是像(>>=)
這樣的實際運算符,而是語法糖的一部分。
至於(2),我要解決的方法是使Msg
成為Functor
:
data Msg a = MNothing | MJust UTCTime a
instance Functor Msg where
fmap f MNothing = MNothing
fmap f (MJust t x) = MJust t (f x)
然后要用字符串連接,可以使用fmap
:
msg' = fmap (++ " in bed") msg
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.