Какова обратная функция Haskell, ожидаемая в этом коде? - PullRequest
1 голос
/ 11 ноября 2019

Я пишу небольшое упражнение на Haskell, оно должно сдвинуть некоторые элементы в списке, подобно шифру Цезаря, код уже работает, код приведен ниже.

module Lib (shift, cipherEncode, cipherDecode ) where
import Data.Char
import Data.List
import Data.Maybe

abcdata :: [Char]
abcdata = ['a','b','c','d','e','f','g']

iabcdata :: [Char]
iabcdata = ['g','f','e','d','c','b','a']

shift :: Char -> Int -> Char
shift l n = if (n >= 0)
            then normalShift l n
            else inverseShift l (abs n)

normalShift :: Char -> Int -> Char
normalShift l n = shifter l n abcdata

inverseShift :: Char -> Int -> Char
inverseShift l n = shifter l n reverse(abcdata) -- This is the line

charIdx :: Char -> [Char] -> Int
charIdx target xs = fromJust $ elemIndex target xs

shifter :: Char -> Int -> [Char] -> Char
shifter l n xs = if (n < length (xs))
            then
                picker ((charIdx l xs) + n) xs
            else
                picker ((charIdx l xs) + (n `mod` length (xs))) xs

picker :: Int -> [Char] -> Char
picker n xs = if n < length xs
              then
                xs!!n
              else
                xs!!(n `mod` length (xs))

ВопросУ меня есть относительно линии

inverseShift l n = shifter l n reverse(abcdata)

Если я изменю ее на

inverseShift l n = shifter l n iabcdata

, она отлично работает

также, когда я делаю reverse(abcdata) == iabcdata, это True, но когда я оставляю reverse в коде, я получаю следующую ошибку

    * Couldn't match expected type `[Char] -> Char'
                  with actual type `Char'
    * The function `shifter' is applied to four arguments,
      but its type `Char -> Int -> [Char] -> Char' has only three
      In the expression: shifter l n reverse (abcdata)
      In an equation for `inverseShift':
          inverseShift l n = shifter l n reverse (abcdata)
   |
21 | inverseShift l n = shifter l n reverse(abcdata)
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    * Couldn't match expected type `[Char]'
                  with actual type `[a0] -> [a0]'
    * Probable cause: `reverse' is applied to too few arguments

Что я делаю неправильно, вызывая shifter с помощью reverse(abcdata)?

Ответы [ 2 ]

7 голосов
/ 11 ноября 2019

Это не то, как работают скобки в Haskell. Как вы написали, reverse и abcdata будут аргументами shifter, но вы хотите, чтобы abcdata был аргументом reverse. Делай shifter l n (reverse abcdata) вместо shifter l n reverse(abcdata).

2 голосов
/ 11 ноября 2019

Что я делаю не так, звоня shifter с reverse(abcdata)?

Ответ - в сообщении:

    * Couldn't match expected type `[Char] -> Char'
                  with actual type `Char'
    * The function `shifter' is applied to four arguments,
      but its type `Char -> Int -> [Char] -> Char' has only three
      In the expression: shifter l n reverse (abcdata)
      In an equation for `inverseShift':
          inverseShift l n = shifter l n reverse (abcdata)

Повтор,

In an equation for `inverseShift': inverseShift l n = shifter l n reverse (abcdata) ~~~~~~~~~~~~~ -- mind the gap!

То, что - это то, как ваше выражение было прочитано Хаскеллом. И это , как вы это написали:

   |
21 | inverseShift l n = shifter l n reverse(abcdata)
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Так что вы на самом деле не звонили shifter с reverse(abcdata).

Вы назвали этос reverse и (abcdata) (а также l и n), как также объясняется в другом ответе.

...