Ich habe eine Funktion, die möglicherweise fehlschlagen, so dass der Wert, den es zurückgibt, in ein Maybe gewickelt werden muss. Es verwendet eine andere Funktion, die ebenfalls fehlschlagen kann und die auch in eine Maybe eingeschlossen ist. Das Problem ist, um die Typen in einer Zwischenrechnung zu berechnen, muss ich eine Funktion "vorzeitig" anheben, um im Maybe-Kontext zu arbeiten. Das führt dazu, dass ich einen Typ bekomme. Vielleicht [Vielleicht Integer], wenn das, was ich will, vielleicht [Integer] ist. Die fragliche Funktion ist die exptDecipherString-Funktion, die Funktion, die "vorzeitiges" Heben erzwingt, ist die modularInverse-Funktion.Wie man ein Extra loswerden kann Vielleicht
import Data.Char
import Control.Applicative
import Control.Monad
import Math.NumberTheory.Powers
--Helpers
extendedGcd::Integer->Integer->(Integer, Integer)
extendedGcd a b | r == 0 = (0, 1)
| otherwise = (y, x - (y * d))
where
(d, r) = a `divMod` b
(x, y) = extendedGcd b r
modularInverse::Integer->Integer->Maybe Integer
modularInverse n b | relativelyPrime n b = Just . fst $ extGcd n b
| otherwise = Nothing
where
extGcd = extendedGcd
relativelyPrime::Integer->Integer->Bool
relativelyPrime m n = gcd m n == 1
textToDigits::String->[Integer]
textToDigits = map (\x->toInteger (ord x - 97))
digitsToText::[Integer]->String
digitsToText = map (\x->chr (fromIntegral x + 97))
--Exponentiation Ciphers
exptEncipher::Integer->Integer->Integer->Maybe Integer
exptEncipher m k p | relativelyPrime k (m - 1) = Just $ powerMod p k m
| otherwise = Nothing
exptDecipher::Integer->Integer->Integer->Maybe Integer
exptDecipher m q c | relativelyPrime q (m - 1) = Just $ powerMod c q m
| otherwise = Nothing
exptEncipherString::Integer->Integer->String->Maybe [Integer]
exptEncipherString m k p | relativelyPrime k (m - 1) = mapM (exptEncipher m k) plaintext
| otherwise = Nothing
where
plaintext = textToDigits p
exptDecipherString::Integer->Integer->[Integer]->Maybe String
exptDecipherString m k c | relativelyPrime k (m - 1) = fmap digitsToText plaintext
| otherwise = Nothing
where
q = modularInverse k (m - 1)
plaintext = mapM (exptDecipher m <$> q <*>) (map pure c)
Ich habe versucht, Hoogle, vielleicht bin ich dumm darüber, wie man es benutzt. Ich tippte "Monad m => m m a-> m a" oder etwas in diesem Sinne ein. Ich versuche immer noch herauszufinden, wie man in Typen denkt :( –
@JoshInfiesto Ihre Frage ist fast richtig! Sie haben gerade einige Klammern vergessen. Versuchen Sie stattdessen 'Monad m => m (ma) -> ma', dann denken Sie nach warum diese Abfrage funktioniert –
Whoops ... Typ Konstruktoren assoziieren links, nicht sie ... –