簡體   English   中英

如何將系統時間傳遞給 Haskell 中的變量

[英]How to pass system time to a variable in Haskell

我正在嘗試使用 Haskell 從系統時鍾獲取當前 POSIX 時間,但出現以下錯誤:

    • No instance for (Show (IO POSIXTime))
        arising from the sixth field of ‘Block’ (type ‘IO POSIXTime’)
      Possible fix:
        use a standalone 'deriving instance' declaration,
          so you can specify the instance context yourself
    • When deriving the instance for (Show Block)
   |
16 |                    , nonce          :: Maybe Integer } deriving Show
   |                                                                 ^^^^

這是上下文的代碼:

import Data.Time
import Data.Time.Clock.POSIX

data Transaction = Transaction { from  :: String
                               , to    :: String
                               , value :: Float } deriving Show

data Block = Block { version        :: Int
                   , index          :: Int
                   , transactions   :: [Transaction]
                   , prevBlockHash  :: String
                   , merkleRootHash :: String
                   , time           :: IO POSIXTime
                   , nonce          :: Maybe Integer } deriving Show

genesis :: Block
genesis = Block version index transactions prevBlockHash merkleRootHash time Nothing
    where version = 1
          index = 0
          transactions = []
          prevBlockHash = "000000000000000000000000000000000"
          merkleRootHash = ""
          time = getPOSIXTime
          nonce = Nothing

我已經參考了許多關於堆棧溢出的類似問題的解決方案,但幾天來一直無法解決該錯誤。

讓我們從使用您擁有的類型的插圖開始

data Block = Block { 
                     version        :: Int
                   -- removed a few field for illustrative purposes 
                   , time           :: IO POSIXTime
                   , nonce          :: Maybe Integer } deriving Show

正如所評論的IO POSIXTime並不是真正的POSIXTime ,而是獲得POSIXTime動作的表示。 讓我們將類型更改為實際的 POSIXTime。

data Block = Block { 
                     version        :: Int
                   , time           :: POSIXTime
                   , nonce          :: Maybe Integer } deriving Show

現在我們可以調整 genesis 來處理我們的新塊:

genesis :: IO Block
genesis = 
  do
     time <- getPOSIXTime
     let version = 1
     let nonce = Nothing
     return (Block version time nonce)

main :: IO ()
main = genesis >>= print
            

請注意我們如何將 IO 從 Block 內部移動到外部,以及它如何與 Haskell 可執行文件始終是IO ()的事實很好地配合。

如果您真的堅持使用Block的這種類型簽名,我會在實現Show (IO POSIXTIme)時使用 go :

instance Show (IO POSIXTime) where 
  show _ = "Time shower"  

您可能會 go 並制作更通用Show (IO a)實例

instance Show (IO a) where 
  show _ = "I can't Show what is inside this IO monad" 

最終,您可以編寫自己的Show Block實例而不是派生它:

instance Show Block where 
  show block = "Block " <> show (version block) <> " .... " 

否則將Block類型簽名更改為POSIXTime不包含在IO中?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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