我正在嘗試使用 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
我已經參考了許多關于堆疊溢位的類似問題的解決方案,但幾天來一直無法解決該錯誤。
uj5u.com熱心網友回復:
讓我們從使用您擁有的型別的插圖開始
data Block = Block {
version :: Int
-- removed a few field for illustrative purposes
, time :: IO POSIXTime
, nonce :: Maybe Integer } deriving Show
正如所評論的那樣,IO POSIXTime它并不是真正的 a POSIXTime,而是獲得 a 的動作的表示POSIXTime。讓我們將型別更改為實際的 POSIXTime。
data Block = Block {
version :: Int
, time :: POSIXTime
, nonce :: Maybe Integer } deriving Show
現在我們可以調整 genesis 來處理我們的新塊: import Data.Time import Data.Time.Clock.POSIX
data Block = Block {
version :: Int
, time :: POSIXTime
, nonce :: Maybe Integer } deriving Show
genesis :: IO Block
genesis =
do
time <- getPOSIXTime
let version = 1
let nonce = Nothing
return (Block version time nonce)
blockTimeAsUTCString :: Block -> String -- No need for IO
blockTimeAsUTCString (Block {time = p}) = show $ posixSecondsToUTCTime p
main :: IO ()
main = ioBlock >>= print >>
ioBlock >>= putStrLn . blockTimeAsUTCString
where ioBlock = genesis
請注意我們如何將 IO 從 Block 內部移到外部,以及它如何與 Haskell 可執行檔案始終為 an 的事實很好地配合,IO ()并blockTimeAsUTCString展示了如何在不依賴 IO 的情況下處理記錄。
uj5u.com熱心網友回復:
如果您真的堅持使用這種型別簽名,Block我將繼續實施Show (IO POSIXTIme):
instance Show (IO POSIXTime) where
show _ = "Time shower"
你可能會去做更一般的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?
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/406843.html
標籤:
