Haskell – используйте Just or No Просто имело значение, но я не знаю, почему
Вопрос
Я нашел такой код в книге «Real World Haskell», стр. 68.
data Tree a = Node a (Tree a) (Tree a)
| Empty
deriving (Show)
nodeAreSame (Node a _ _) (Node b _ _)
| a == b = Just a
nodeAreSame _ _ = Nothing
Мой вопрос:Какую работу выполнял Just
конструктор данных делать?Когда я удалю его, я получу сообщение об ошибке, например
(in ghci)
......
<Main *> nodeAreSame (Node 3 Empty Empty) (Node 3 Empty Empty))
<interactive>:1:16:
No instance for (Num (Maybe a))
......
Но когда я пытаюсь сравнить разницу типов между версиями «Just» и «No Just»:
nodeAreSameJust :: (Eq t) => Tree t -> Tree t -> Maybe t
nodeAreSameNoJust :: (Eq a) => Tree (Maybe a) -> Tree (Maybe a) -> Maybe a
Так что же здесь ключевого момента?Означает ли это, что когда я помещаю переменную с типом a
в узле функция не выведет узел типа a
, поэтому возникает ошибка?
Решение
Фактически отсутствие Just
делает нет сделайте это некорректно.
Вот сделка.Код
nodeAreSame (Node a _ _) (Node b _ _)
| a == b = a
nodeAreSame _ _ = Nothing
является хорошо напечатано при условии, что a
и b
относятся к типу Maybe t
для некоторых t
, поскольку это тип Nothing
.Таким образом, система типов делает такой вывод.
Теперь, когда у вас есть числовой литерал типа 3
, предполагается, что он имеет тип Num s => s
до тех пор, пока вы фактически не примените его к определенному типу данных (например, Int
или Double
).
Поэтому, когда он объединяет эти два факта, он предполагает следующее:
Num (Maybe t) => 3 :: Maybe t
.
Поскольку нет примера для Num (Maybe t)
, он жалуется в этот момент, прежде чем получит возможность пожаловаться на это 3 :: Maybe t
без разницы.
Другие советы
Что еще вы ожидаете вернуть, просто a
?Это не сработает, потому что a
и Nothing
не одного типа.Все определения функции должны возвращать один и тот же тип. Nothing
и Just a
совпадают, потому что они оба одного типа Maybe a
.
В этом нет просто версии, это требует элемента на дереве, чтобы быть типом, может быть, а.
Я не совсем уверен, что причина, причина, например, ошибка, например, NUM (может быть).Я думаю, что ошибка более восхищает, если вы используете строку вместо 3.
*Main> nodeAreSameNoJust (Node "arst" Empty Empty) (Node "arst" Empty Empty)
<interactive>:1:24:
Couldn't match expected type `Maybe a'
against inferred type `[Char]'
In the first argument of `Node', namely `"arst"'
In the first argument of `nodeAreSameNoJust', namely
`(Node "arst" Empty Empty)'
In the expression:
nodeAreSameNoJust
(Node "arst" Empty Empty) (Node "arst" Empty Empty)
.
Здесь яснее, что ожидает чего-то такого типа, может быть.В обоих случаях второй случай функции ничто, поэтому тип результата выводится, может быть, может быть.Включая только то значение, которое вы используете в дереве дерева, затем помещают в Ally Type.Без этого он ожидает, что приводят к тому же типу, так как ничто, поскольку каждая часть функции должна быть одинаковым типом.