Haskell 代码中函数 (toEnum . fromEnum) 的用途是什么?

tom*_*tom 6 haskell

我看到了toEnum . fromEnumChars in上使用的函数HaskellNet.Network.Auth

b64Encode :: String -> String
b64Encode = map (toEnum.fromEnum) . B64.encode . map (toEnum.fromEnum)

b64Decode :: String -> String
b64Decode = map (toEnum.fromEnum) . B64.decode . map (toEnum.fromEnum)
Run Code Online (Sandbox Code Playgroud)

乍一看这个功能应该和 一样id吧?为什么会在这里?

bra*_*drn 6

可以等价于id,但仅限于某些情况。由于fromEnum :: Enum a => a -> Int可以转换任何 Enum一种Int,并且toEnum :: Enum a => Int -> a可以将转换Int任何 Enum,接下去toEnum . fromEnum是从变换的一般方法的任何枚举的任何枚举-也就是说,(toEnum . fromEnum) :: (Enum a, Enum b) => a -> b。正如您所观察到的,这确实应该与id(如果Enum实例已正确实现)相同,但仅当您选择ab作为相同类型时;否则,它将从一个Enum实例转换为另一个Enum实例。

至于为什么在那个特定的地方使用它:我真的不知道。B64.decodeB64.encode出现两者String -> String,并且b64Decodeb64Encode String -> String,所以toEnum . fromEnum将来自CharChar-所以在这种情况下,它应该是相同的id。换句话说,toEnum . fromEnum这里什么都不做,可能应该被删除(虽然我不排除Enum实例的Char实现方式 this is not的可能性id)。

编辑: @KABuhr 在项目的 Git 历史中找到了对此的解释。似乎encodedecode曾经有涉及的签名ByteString,所以toEnumfromEnum被用来在Word8(for ByteString) 列表和Char(for String)列表之间进行转换。在某些时候encodedecode并切换到使用String而不是ByteString,但没有人删除toEnumfromEnum

  • 查看该项目的 Git 历史记录,看起来“B64”用于引用模块“Codec.Binary.Base64”,其中“encode”和“decode”在“ByteString”上工作,因此这些函数用于在“ByteString”之间进行转换“字节串”和“字符串”。在某些时候,有人将“B64”切换为模块“Codec.Binary.Base64.String”,但没有费心将定义更新为“b64Encode = B64.encode”和“b64Decode = B64.decode”。 (2认同)