Как ввести переменную в область видимости и как сопоставить типы - PullRequest
1 голос
/ 26 октября 2019

Каждый раз, когда я пытаюсь загрузить модуль, содержащий func1, я сталкиваюсь с ошибкой, и я не знаю, как ее исправить.

func2 и func3 работают независимо и выполняют именно то, что должныdo.

func1 xs = [x| let x = func2 (-c) xs, (_,c) <- func3 xs] 

func1 ожидает строку и должен доставить другую строку. xs - входная строка, x - выходная строка. func 2 ожидает Int и String, c - Int и создает другую String. func3 ожидает String и выдает Tuple. (_, c) - Выход, первый элемент _, потому что он не имеет отношения к этой функции, а второй элемент - целое число.

Нет выходных данных, и я получаю следующее сообщение об ошибке:

Programm.hs:205:18: error:
    Variable not in scope: c :: Integer
    |
205 |         func2 (-c) xs
    |                  ^

Programm.hs:208:16: error:
    * Couldn't match type `[Char]' with `Char'
      Expected type: Char
        Actual type: String
    * In the expression: x
      In the expression:
        [x | let x = func2 (- c) xs, (_, c) <- func3 xs]
      In an equation for `decypher':
          func1 xs = [x | let x = func2 (- c) xs, (_, c) <- func3 xs]
    |
208 | func1 xs = [x| let x = func2 (-c) xs, (_,c) <- func3 xs]
    |                

Programm.hs:208:36: error:
    Variable not in scope: c :: Int
    |
208 | func1 xs = [x| let x = func2 (-c) xs, (_,c) <- func3 xs]
    |                                    
Failed, no modules loaded.

Теперь мои вопросы: почему он говорит, что c не является целым числом, когда я определил его (я также попробовал это с «let (_, c) = func3 xs») в качестве второго элементавывод func3, который обязательно является целым числом?

Почему ожидается, что x будет Char, если на выходе func2 обязательно будет String?

Заранее спасибо, и пожалуйстатерпение со мной, я только учу Haskell: *

1 Ответ

1 голос
/ 26 октября 2019

Вы должны поменять местами порядок предложений let и предложения генератора:

func1 xs = [ x | (_,<b>c</b>) <- func3 xs, let x = func2 (-<b>c</b>) xs ]

, но поскольку здесь вы используете только x в части "yield" понимания списка, выможете просто пропустить let x = &hellip; и работать с:

func1 xs = [ <b>func2 (-c) xs</b> | (_,c) <- func3 xs ]

На основе подписей вашей функции :

func1 :: String -> String
func2 :: Int -> String -> String
func3 :: String -> (Float,Int)

ваш func3 не делаетвернуть список: он возвращает 2-кортеж. В этом случае ваш func1 должен выглядеть следующим образом:

func1 :: String -> String
func1 = negate . snd . func3 >>= func2

или проще:

func1 :: String -> String
func1 xs = func2 (- (snd (func3 xs))) xs
...