Мне нужно написать программу, которая декодирует список из четырех значений, который может быть либо I, либо O в список [Either Bool Bool]
. Я знаю, что я должен использовать, может быть, но я просто не могу обвести вокруг себя голову. Сейчас я полностью отчаянный, потому что я просто не могу решить эту проблему.Haskell beginner не может соответствовать ожидаемому типу
Пример ввода и вывода может выглядеть следующим образом: [I, O, O, I] => [Left Правда, правый Ложные]
Вот текущий код у меня есть:
module Blueprint where
import Prelude
import Data.Maybe
data Bit = O | I deriving (Eq, Show)
encode :: [Either Bool Bool] -> [Bit]
encode [] = []
encode l = case head l of
Left False -> [I, I] ++ encode (tail l)
Left True -> [I, O] ++ encode (tail l)
Right False -> [O, I] ++ encode (tail l)
Right True -> [O, O] ++ encode (tail l)
decode :: [Bit] -> Maybe [Either Bool Bool]
decode [] = Nothing
decode [x] = Nothing
decode l = if isNothing (decode (tail (tail l)))
then Nothing
else case head l of
I -> if l!!1 == I
then [Left False] ++ decode (tail (tail l))
else [Left True] ++ decode (tail (tail l))
O -> if l!!1 == I
then [Right False] ++ decode (tail (tail l))
else [Right True] ++ decode (tail (tail l))
и эти ошибки я получаю:
Prelude> :load serialise
[1 of 1] Compiling Blueprint (serialise.hs, interpreted)
serialise.hs:22:16:
Couldn't match expected type `Maybe [Either Bool Bool]'
with actual type `[Either Bool b0]'
In the expression: [Left False] ++ decode (tail (tail l))
In the expression:
if l !! 1 == I then
[Left False] ++ decode (tail (tail l))
else
[Left True] ++ decode (tail (tail l))
In a case alternative:
I -> if l !! 1 == I then
[Left False] ++ decode (tail (tail l))
else
[Left True] ++ decode (tail (tail l))
serialise.hs:22:33:
Couldn't match expected type `[Either Bool b0]'
with actual type `Maybe [Either Bool Bool]'
In the second argument of `(++)', namely `decode (tail (tail l))'
In the expression: [Left False] ++ decode (tail (tail l))
serialise.hs:23:16:
Couldn't match expected type `Maybe [Either Bool Bool]'
with actual type `[Either Bool b1]'
In the expression: [Left True] ++ decode (tail (tail l))
In the expression:
if l !! 1 == I then
[Left False] ++ decode (tail (tail l))
else
[Left True] ++ decode (tail (tail l))
In a case alternative:
I -> if l !! 1 == I then
[Left False] ++ decode (tail (tail l))
else
[Left True] ++ decode (tail (tail l))
serialise.hs:23:32:
Couldn't match expected type `[Either Bool b1]'
with actual type `Maybe [Either Bool Bool]'
In the second argument of `(++)', namely `decode (tail (tail l))'
In the expression: [Left True] ++ decode (tail (tail l))
serialise.hs:25:16:
Couldn't match expected type `Maybe [Either Bool Bool]'
with actual type `[Either a0 Bool]'
In the expression: [Right False] ++ decode (tail (tail l))
In the expression:
if l !! 1 == I then
[Right False] ++ decode (tail (tail l))
else
[Right True] ++ decode (tail (tail l))
In a case alternative:
O -> if l !! 1 == I then
[Right False] ++ decode (tail (tail l))
else
[Right True] ++ decode (tail (tail l))
serialise.hs:25:34:
Couldn't match expected type `[Either a0 Bool]'
with actual type `Maybe [Either Bool Bool]'
In the second argument of `(++)', namely `decode (tail (tail l))'
In the expression: [Right False] ++ decode (tail (tail l))
serialise.hs:26:16:
Couldn't match expected type `Maybe [Either Bool Bool]'
with actual type `[Either a1 Bool]'
In the expression: [Right True] ++ decode (tail (tail l))
In the expression:
if l !! 1 == I then
[Right False] ++ decode (tail (tail l))
else
[Right True] ++ decode (tail (tail l))
In a case alternative:
O -> if l !! 1 == I then
[Right False] ++ decode (tail (tail l))
else
[Right True] ++ decode (tail (tail l))
serialise.hs:26:32:
Couldn't match expected type `[Either a1 Bool]'
with actual type `Maybe [Either Bool Bool]'
In the second argument of `(++)', namely `decode (tail (tail l))'
In the expression: [Right True] ++ decode (tail (tail l))
Failed, modules loaded: none.
Сейчас ничего, что помогает мне решить эту проблему можно только приветствовать. Я пробовал это в течение большей части дня, и я просто не могу его решить.
Также обратите внимание, что новая версия использует только общие методы, что делает ее более безопасной. Учет соответствия шаблону 'x/y' позволяет избежать того, можно ли безопасно выполнять' head' или '!! 1'. Несмотря на то, что после анализа это безопасно, полезно избегать анализа. – Guvante
@Ruhrpottpatriot: Понимание монады «Может быть» требует понимания монадов. В этом случае преобразование простое, вы можете удалить 'return' /' do' и заменить 'end <- decode rest' на предоставленный фрагмент, и вы будете иметь идентичное выполнение. Я всегда думаю о монаде «Maybe» как «если' <-' возвращает 'Nothing' вы в конечном итоге с' Nothing' и 'return' является синонимом' Just' ' – Guvante
@Ruhrpottpatriot тип 'Maybe' определяется как 'data Может быть a = Nothing | Просто. В этом нет ничего особенного, у типа только два конструктора: 'Nothing :: Maybe a' и' Just :: a -> Maybe a'. Чтобы построить значение типа 'Maybe a', вы используете один из этих двух конструкторов. Применение 'Just' к значению типа' a' создает новое значение типа 'Maybe a', а использование' Nothing' просто строит значение типа 'Maybe a', никаких входных данных не требуется. – bheklilr