Почему Haskell выдает ошибку типа, если я жестко кодирую возвращаемое значение? - PullRequest
2 голосов
/ 01 марта 2010

Я действительно затрудняюсь объяснить, почему это ошибка типа:

foo :: (Eq a) => a -> a
foo _ = 2

Может кто-нибудь объяснить?

Ответы [ 2 ]

14 голосов
/ 01 марта 2010

Потому что тип

foo "bar"

должно быть строкой, в соответствии с вашей подписью, но не является (2 не является строкой). В вашем коде foo является универсальным, поэтому он должен возвращать экземпляр того же типа, что и аргумент.

Сила системы типов haskell дает нам дополнительную информацию - все, что вы можете сделать с аргументом внутри foo, это проверить его равенство с чем-то другим, но я могу придумать любой новый тип (давайте назовем его Baz) и используйте для этого foo - у вас не может быть других экземпляров Baz, поэтому единственный способ вернуть экземпляр Baz - это вернуть тот же экземпляр, что и аргумент.

Если вы переписали foo следующим образом:

foo _ = True

он будет иметь подпись foo :: a -> Bool, это в основном то, что вы пытались сделать, но с числами все усложняется.

В общем, ваша функция имеет подпись

foo :: (Num t1) => t -> t1

, что означает, что он возвращает экземпляр Num для любого заданного аргумента. (Это потому, что 2 может иметь много разных типов в haskell, в зависимости от того, что вам нужно, это может быть Int, Real или другое.)

Вам следует поиграться с типами в ghci, например:

:t foo

выдаст вам подпись типа infred для foo.

:t 2

дает вам (Num t) => t, что означает, что 2 может быть экземпляром любого типа, который реализует Num.

5 голосов
/ 01 марта 2010

Подпись типа, которую вы объявили, означает

для всех типов a (который создает Eq), foo принимает значение этого типа и возвращает другое значение этого типа

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

foo :: forall a . Eq a => a -> a

Теперь определение функции

foo _ = 2

говорит что-то другое:

Независимо от того, какой тип указан, вернуть число.

И, конечно, эти типы несовместимы.

Пример: как сказал Михал, поскольку foo "Hello" получает String, он должен возвращать строку, но на самом деле возвращает число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...