Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read
Q&A

Why does my code show an error at deriving (eq)? (SOLVED) NEW ERROR: At SimpleEnigma & SteckeredEnigma constructors which I need help on :")

+0
−1

Hi, I'm trying to code an Enigma machine in Haskell which were used by the German in WWII to transmit coded messages. An Enigma Machine consists of 3 rotors which are substitution ciphers and a reflector which contains 13 pairs of characters. To encode a character it is first encoded by the first rotor, then the encoded character from this is passed to the second rotor and then so on through one more rotor to a reflector which swaps this new character with the one it is paired with. This paired character is then encoded in reverse back the opposite way through the rotors until you end up with a final encoded character.

Before an individual character is encoded the rotors are shifted. If you had a very long message, before anything is encoded the first rotor is shifted one place, this character is then passed through the system and encoded. Then before the second character is encoded the first rotor is shifted again. The rotor is continually shifted until it reaches the start again. After the 25th character has been encoded, the first rotor reaches where it started from but now the second rotor shifts one place. The first rotor then turns another 26 times before the second rotor turns again. When the second rotor has turned 26 times the third rotor turns once. This keeps happening until 25 25 25 is reached at which point they reset back to 0 0 0 and the cycle starts again.

My problems: The deriving (eq) here (I've added a comment beside it so it stands out) has been solved, thank you. Currently, it says that:

Constructor 'SimpleEnigma' should have 5 arguments, but was given none in the pattern: SimpleEnigma. In a pattern binding: SimpleEnigma = SimpleEnigma rotor1 rotor2 rotor3 reflectorB offsets typecheck

Constructor 'SteckeredEnigma' should have 6 arguments, but was given none in the pattern: SteckeredEnigma. In a pattern binding: SteckeredEnigma = SteckeredEnigma rotor1 rotor2 rotor3 reflectorB offsets typecheck

How can I resolve the issue here?

Also I'm not done yet (just coded halfway) so if you see that I'm missing something please tell me about it, I'm also not sure if I'm coding it right as well.

  import Data.Char  
  import Data.Maybe 

{- Part 1: Simulation of the Enigma -}

  type Rotor = (String, Enigma) 
  type Reflector = [(Char, Char)] 
  type Offset = Int 
  type Offsets = (Offset, Offset, Offset)
  type Stecker = [(Char, Char)] 
  --Plugboard is the stecker 

  
  data Enigma = SimpleEnigma Rotor Rotor Rotor Reflector Offsets
                | SteckeredEnigma Rotor Rotor Rotor Reflector Offsets Stecker
    deriving (eq) -- ERROR here with a red underline on eq (ERROR FIXED)

  {-ERROR BELOW: Constructor 'SimpleEnigma' should have 5 arguments, but was given none in the pattern: SimpleEnigma. 
Constructor 'SteckeredEnigma' should have 6 arguments, but was given none in the pattern: SteckeredEnigma.-}
  SimpleEnigma = SimpleEnigma rotor1 rotor2 rotor3 reflectorB offsets
  SteckeredEnigma = SteckeredEnigma rotor1 rotor2 rotor3 reflectorB offsets steckerB 


  offset_step :: Offsets->Offsets
  offset_step (l, m, 25) = offset (l, m, 0) --left, middle, right
  offset_step (l, m, r) = (l, m, r+1)

  offsetlm :: Offsets->Offsets
  offsetlm (l, 25, 0) = (offset)
  offsetlm (l,m,0)=(l,m+1,0)

  offsetl :: Offsets->Offsets
  offsetl (25,0,0)= (0,0,0)
  offsetl (l,0,0)=(l+1,0,0)

  offsetN :: Offsets->Int->Offsets
  offsetN os 0 = os
  offsetN os n = offsetN (offset_step os) (n-1)


  offsetN os 0 = os
  offsetN os n = offsetN (offset_step os) (n-1)

  enigmaEncodeA x (SimpleEnigma lr mr rr ref) (ol,om,or)=
    reverseEncode rr or     -- left rotor returning
    (reverseEncode mr om    -- middle rotor returning
      (reverseEncode lr ol  -- left rotor returning
       (reflect -- fixed reflector
        (encode lr ol -- left rotor forward
          (encode mr om-- mid rotor forward
                 (encode rr or x) -- right rotor forward
          )
        )
        ref
       )
      )
     )

  encodeMessage :: String -> Enigma -> String
  encodeMessage _ _ = "" -- you need to complete this!
  encodeMessage x e os = enigmaEncodeA x e (offset_step os)


{- Useful definitions and functions -}

   -- substitution cyphers for the Enigma rotors
   -- as pairs of (wirings, knock-on position)
   -- knock-on position is where it will cause the next left wheel to
   -- advance when it moves past this position
 
        --"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  rotor1=("EKMFLGDQVZNTOWYHXUSPAIBRCJ",17::Int) --Knock-on position:17
  rotor2=("AJDKSIRUXBLHWTMCQGZNPYFVOE",5::Int)  --Knock-on position: 5
  rotor3=("BDFHJLCPRTXVZNYEIWGAKMUSQO",22::Int) 
  rotor4=("ESOVPZJAYQUIRHXLNFTGKDCMWB",10::Int)
  rotor5=("VZBRGITYUPSDNHLXAWMJQOFECK",0::Int)

  
  {- the standard Enigma reflector (Reflector B)
    swapped A<->Y, B<->R, C<->U,D<->H, E<->Q, F<->S, G<->L, 
            I<->P, J<->X, K<->N, M<->O, T<->Z,V<->W
  -}
  reflectorB= [('A','Y'),
              ('B','R'),
              ('C','U'),
              ('D','H'),
              ('E','Q'),
              ('F','S'),
              ('G','L'),
              ('I','P'),
              ('J','X'),
              ('K','N'),
              ('M','O'),
              ('T','Z'),
              ('V','W')]

  {- alphaPos: given an uppercase letter, returns its index in the alphabet
     ('A' = position 0; 'Z' = position 25)
   -}
  alphaPos :: Char -> Int
  alphaPos c = (ord c) - ord 'A'

I've added a picture of how the Enigma machine words by mapping the characters and creating offsets for the rotors for your reference, below: Enigma Machine Algorithm

Thanks, any help is greatly appreciated!! :-)

Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

1 answer

+2
−0

Eq is a type class, and type class names are capitalized (like types and constructors). Changing eq to Eq should get you past that error.

Conversely, in

  SimpleEnigma = SimpleEnigma rotor1 rotor2 rotor3 reflectorB offsets
  SteckeredEnigma = SteckeredEnigma rotor1 rotor2 rotor3 reflectorB offsets steckerB

you'll need to change the things you're defining to start with a lowercase letter. (What you have is doubly wrong: it's invalid to declare a variable with a capitalized name, and even if it weren't, SimpleEnigma and SteckeredEnigma are already defined as the constructors of Enigma.)

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Hi I have a new question, I thought I posted it here but it seems as if it's a comment to my question... (3 comments)

Sign up to answer this question »