박신환

2018-07-29 09:44:33 UTC

For use of ciphers (SHA-256, RSA-2048, etc.), a type must be able to be injectively mapped to integers. It seems `Enum` is currently the closest thing that does this.

But `Enum` is supposed to be for arithmetic sequences, so it seems better to define a new typeclass. (Here named `Cipherable`)

There are some types that aren't members of `Enum`. For example, `Maybe`, `[]`, etc. They seem okay to be Cipherable. Hence:

{-# LANGUAGE ScopedTypeVariables #-}

ï»¿

instance Cipherable a => Cipherable (Maybe a) where

toEnum 0 = Nothing

toEnum n = Just (toEnum n)

fromEnum Nothing = 0

fromEnum (Just x) = 1 + fromEnum x

instance forall a. (Cipherable a, Bounded a) => Cipherable [a] where

toEnum 0 = []

toEnum n = let

(q,r) = (n-1) `quotRem` (1 + fromEnum (maxBound :: a))

in toEnum r : toEnum q

fromEnum [] = 0

fromEnum (x:xs) = 1 + fromEnum x + (1 + fromEnum (maxBound :: a)) * fromEnum xs

instance Cipherable Void where

toEnum = errorWithoutStackTrace "Cipher.Cipherable.Void.toEnum"

fromEnum = absurd

(Besides, it is possible to re-write that of `[]` without ScopedTypeVariables? I see no way...)

But `Enum` is supposed to be for arithmetic sequences, so it seems better to define a new typeclass. (Here named `Cipherable`)

There are some types that aren't members of `Enum`. For example, `Maybe`, `[]`, etc. They seem okay to be Cipherable. Hence:

{-# LANGUAGE ScopedTypeVariables #-}

ï»¿

instance Cipherable a => Cipherable (Maybe a) where

toEnum 0 = Nothing

toEnum n = Just (toEnum n)

fromEnum Nothing = 0

fromEnum (Just x) = 1 + fromEnum x

instance forall a. (Cipherable a, Bounded a) => Cipherable [a] where

toEnum 0 = []

toEnum n = let

(q,r) = (n-1) `quotRem` (1 + fromEnum (maxBound :: a))

in toEnum r : toEnum q

fromEnum [] = 0

fromEnum (x:xs) = 1 + fromEnum x + (1 + fromEnum (maxBound :: a)) * fromEnum xs

instance Cipherable Void where

toEnum = errorWithoutStackTrace "Cipher.Cipherable.Void.toEnum"

fromEnum = absurd

(Besides, it is possible to re-write that of `[]` without ScopedTypeVariables? I see no way...)