2016-11-28 3 views
1

У меня есть код Haskell ниже. Проблема в том, что статья (enigmaInput,_) = (filter (\(a,b) -> b == cipherChar0) stecker)!!0 потерпит неудачу для первых двух охранников. Как я могу назначить его только для 2-х охранников. Благодаря!Где предложение для конкретного охранника

followMenu :: Crib->Menu->Stecker->Offsets->Maybe Stecker 
followMenu c [] s o = Just s 
followMenu crib menu stecker offsets 
    | (length stecker) == 1 && initAdd == Nothing = Nothing 
    | (length stecker) == 1 && initAdd /= Nothing = followMenu crib (tail menu) (fromMb initAdd) offsets 
    | (length stecker) /= 1 && normalAdd == Nothing = Nothing 
    | otherwise = followMenu crib (tail menu) (fromMb normalAdd) offsets 
    where (_,_,cipherChar0) = crib!!(menu!!0) 
     (_,_,cipherChar1) = crib!!(menu!!1) 
     (enigmaInput,_) = (filter (\(a,b) -> b == cipherChar0) stecker)!!0 
     enigmaOutput = enigmaEncode enigmaInput (SimpleEnigma rotor3 rotor2 rotor1 reflector1) offsets 
     (_,initInput) = stecker!!0 
     initOutput = enigmaEncode initInput (SimpleEnigma rotor3 rotor2 rotor1 reflector1) offsets 
     (_,_,initCipher) = crib!!(menu!!0) 
     initAdd = steckerAdd initOutput initCipher stecker 
     normalAdd = steckerAdd enigmaOutput cipherChar1 stecker 
+2

Вам не хватает большой возможности для упрощения кода. Вам не нужно явно проверять, какие значения имеют значения «initAdd» и «normalAdd»; просто определите 'fm = \ add -> followMenu crib (tail menu) add offsets', затем вызовите' fmap fm initAdd' и 'fmap fm normalAdd' в зависимости от длины' stecker'. – chepner

+1

Также совпадение шаблонов на 'stecker' вместо проверки длины и индексации также очистит вещи, я думаю, что это даже затронет ваш вопрос. – luqui

ответ

1

Вы на самом деле не нужно, так как (filter (\(a,b) -> b == cipherChar0) stecker)!!0 не будет оценена, пока значение enigmaInput не требуется, и вы не используете enigmaInput в первых двух случаях охраны. Это приятная особенность ленивой оценки.

Невозможно приложить предложение where к некоторому, но не ко всему набору защищенных уравнений, кроме того, чтобы реструктурировать ваши шаблоны и защитные меры, конечно.

+1

Когда я пытаюсь использовать 2 элемента 'stecker', он отлично работает, но когда я пытаюсь использовать 1 элемент' stecker', я получил эту ошибку '*** Exception: Prelude. !!: index too large', поэтому я думаю, что это из-за' (filter (\ (a, b) -> b == cipherChar0) stecker) !! 0' возвращает пустой список для 1 элемента 'stecker' –

+1

Ну, это невозможно, если вы действительно не используете' enigmaInput' ни в одном из первых два случая. Это скорее одно из многих других применений '!!' в вашей программе. –

Смежные вопросы