考慮以下代碼:
-- | Parse a 64bit word in little-endian format.
word64le :: Get ByteString e Word64
word64le = do
s <- elems 8
pure $ foldl' (.|.) 0 [shiftL (fromIntegral b) (i * 8) | (i, b) <- zip [0 .. 7] (atomize s)]
elems根據評論,這通過首先拉出一個 8 位元組的 ByteString(呼叫),然后將其解包(atomize呼叫)并進行明顯的左移舞來從 ByteString 中讀出 Word64 。到目前為止,一切都很好。現在這段代碼可以很明顯地推廣到其他機器整數型別,我們只需要掌握這種型別的位數,這是由 FiniteBits 類提供的。所以做概括:
-- | Parse an integral word in little-endian format.
integralLe :: (FiniteBits w, Integral w, Bounded w) => Get ByteString e w
integralLe = do
s <- elems (fromIntegral n)
pure $ foldl' (.|.) 0 [shiftL (fromIntegral b) (i * 8) | (i, b) <- zip [0 .. n - 1] (atomize s)]
where
n = finiteBitSize (minBound :: w) `quot` 8
這不起作用,GHC 抱怨“無法從背景關系中推斷出(有界 w1)因使用 'minBound' 而產生:(FiniteBits w, Integral w, Bounded w)”。因此,似乎我的型別注釋minBound :: w不足以讓 GHC 相信我的意思與w函式簽名中的相同;我的診斷正確嗎?如果是,我如何告訴 GHC 這兩個 w 型別是相同的?
筆記):
- 在 GHC 9.2 上,每晚堆疊。
- 對糟糕的問題標題感到抱歉,但想不出更好的辦法。
編輯:
- 根據在檔案頂部添加但具有相同錯誤的注釋
{-# LANGUAGE ScopedTypeVariables #-},即“無法從背景關系中推斷出(有界 w2)因使用 'minBound' 而產生:(FiniteBits w, Integral w, Bounded w)由型別簽名:" - 啊哈。如果我
forall e w .在約束左側的函式簽名中添加顯式,即使沒有 ScopedTypedVariables 擴展(可能是因為我使用的是 GHC2021 語言),它也可以作業。不,要理解為什么這會起作用......
uj5u.com熱心網友回復:
Haskell 有一些……讓我們親切地稱它為“奇怪”……關于默認情況下型別變數如何限定范圍的規則。
-- | Parse an integral word in little-endian format.
integralLe :: (FiniteBits w, Integral w, Bounded w) => Get ByteString e w
integralLe = do
s <- elems (fromIntegral n)
pure $ foldl' (.|.) 0 [shiftL (fromIntegral b) (i * 8) | (i, b) <- zip [0 .. n - 1] (atomize s)]
where
n = finiteBitSize (minBound :: w) `quot` 8
你是對的,Haskell 會forall w在型別簽名的開頭拋出一個隱式integralLe,但它實際上并不是一個ScopedTypeVariablesforall。默認情況下,該變數的范圍就是那一行。它不where被視為子句、子句或函式內let任何其他內容中的任何型別歸屬或簽名中的型別變數。這就是進來的地方。使用,顯式使型別變數在詞法上可用于函式體內的任何內容,包括塊。(并且,正如您正確指出的那樣,包含在 中)。因此,ScopedTypeVariablesScopedTypeVariables forallwhereScopedTypeVariablesGHC2021
integralLe :: forall w. (FiniteBits w, Integral w, Bounded w) => Get ByteString e w
將作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/531106.html
標籤:哈斯克尔
上一篇:Haskell函式的時間復雜度
下一篇:如何在回圈中命令Ajax呼叫
