簡體   English   中英

編寫我自己的日志數據類型haskell

[英]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用於兩條消息,這將花費消息中最早的時間。

我的問題是:

  1. 對於Msg類型,我在創建MJust變量時遇到了麻煩,原因是調用getCurrentTime返回IO UTCTime ,而我想擁有UTCTime 我該如何解決?

  2. 我只能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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM