Мне пришлось написать свою собственную функцию распаковки. Теперь мне нужно написать примеры. Но я не могу работать с пустыми списками:
example_unzip_1 = unzip [] == ([],[])
Я пробовал несколько вещей, но больше всего я ожидал, что это сработает:
example_unzip_1 = unzip []::[(a,b)] == ([],[])::([a],[b])
Я знаю, что ошибка связана с типами, но я не знаю, что делать.
Я обновил выражения, потому что комментарии показали, что я недостаточно ясен.
example_unzip_1 должно быть истинным.
и определение функции:
DEFINITION
> unzip [] = ([],[])
> unzip ((a,b):xs) = (a:as, b:bs)
> where (as, bs) = unzip xs
Читая ваш пост, я не могу точно сказать, является ли ваш код реализацией вашего распаковки или двумя примерами, которые, по вашему мнению, должны быть правдой. Можете ли вы опубликовать код своей функции вместе с сигнатурой типа, которая у нее есть?
unzip [] = ([],[]) с одним знаком равенства — это вполне допустимая строка кода. Теперь вам также нужно другое уравнение для обработки непустых входных списков.
Извините ребята. Мой вопрос показался недостаточно ясным.





Если вы введете unzip [] == ([],[]) в GHCi, он будет правильно оценен как True, но когда вы добавите строку example_unzip_1 = unzip [] == ([],[]) в файл и попытаетесь открыть его, вы получите ошибку типа. Почему это? На техническом жаргоне GHC это связано с «ограничением мономорфизма», но на практике это означает, что GHC не знает, какой тип списков вы используете.
В GHCi интерпретатор автоматически делает некоторые настройки по умолчанию за вас. Если вы введете число, например 3, оно распечатается 3. Но если вы спросите тип 3 с :t 3, вы увидите, что он говорит 3 :: Num p => p. Итак, если GHCi знает только то, что 3 — это тип, являющийся экземпляром Num, то как он смог это показать? И почему он не показывает это как 3.0, если вы ввели Float? Что ж, в отсутствие дополнительной информации GHCi «по умолчанию» использует тип Integer и использует экземпляр Show для Integer. Когда вы вводите unzip [] == ([],[]), по умолчанию также устанавливаются типы списков, присваивая им конкретный тип и экземпляр Eq.
Вы на правильном пути со второй попыткой (то есть example_unzip_1 = unzip []::[(a,b)] == ([],[])::([a],[b])), но здесь есть две проблемы. Во-первых, GHC немного привередлив к переменным типа, и в этом случае, поскольку вы не ввели свои переменные типа с ключевым словом forall (что также требует использования некоторых языковых расширений, вероятно ScopedTypeVariables), GHC на самом деле не понимает, что a слева совпадает с a справа. Но несмотря на это, GHC по-прежнему не будет знать, какие фактические типы использовать при проверке на равенство!
Способ исправить это — использовать фактические конкретные типы. Например, вы можете написать:
example_unzip_1 = unzip []::[(Int,())] == ([],[])::([Int],[()])
Это правильно напечатает check. На самом деле, из-за хорошего вывода типов GHC вам нужна только одна аннотация типа, поэтому вы можете упростить это до:
example_unzip_1 = unzip []::[(Int,())] == ([],[])
В Haskell вы определяете новую сущность с помощью одного знака «=». Это известно как оператор присваивания. Нравится:
newEntity = definition of new entity; двойной знак равенства "= = " используется только для проверки равенства двух уже определенных объектов, как в языках C и C++.