Как получить maxBound типа с экземпляром Bounded - PullRequest
0 голосов
/ 19 января 2019

Следующий код на Haskell не компилируется:

getMaxBound :: (Bounded a) => a -> a
getMaxBound _ = maxBound :: a

Я получаю следующую ошибку:

Could not deduce (Bounded a1) arising from a use of ‘maxBound’
  from the context: Bounded a
    bound by the type signature for:
               getMaxBound :: Bounded a => a -> a
    at rot13.hs:3:1-36

Почему я не могу получить maxBound ограниченного типа вHaskell?

В идеале я бы использовал эту функцию следующим образом:

getMaxBound 3
> 9223372036854775807

getMaxBound 'c'
> '\1114111'

Я чувствую, что каждый раз, когда у меня есть любой тип a, имеющий экземпляр Bounded, я должен иметь возможностьполучить maxBound этого типа.

Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 19 января 2019

В этом случае ответ Виллема должен работать очень хорошо, но альтернативой, которая также может быть полезна в более сложных случаях, является использование -XScopedTypeVariables

если вы добавите строку {-# LANGUAGE ScopedTypeVariables #-} в начало файла, ваш код должен скомпилироваться.

то, что делает расширение, позволяет вам ссылаться на переменные типа из внешней области видимости во внутренней области видимости. в вашем коде a затеняется в теле функции, и между ним и внешним a нет никакой связи, что приводит к потере контекста Bounded a!

0 голосов
/ 19 января 2019

Подпись типа достаточна

Поскольку подпись уже ограничивает тип, вы можете удалить часть :: a в теле функции:

getMaxBound :: Bounded a => <b>a</b> -> <b>a</b>
getMaxBound _ = maxBound

Подпись типа указывает этот типвход функции совпадает с типом выхода функции.

Например:

Prelude> getMaxBound (3 :: Int)
9223372036854775807
Prelude> getMaxBound 'c'
'\1114111'
Prelude> getMaxBound True
True
Prelude> getMaxBound LT
GT

Использование расширения ScopedTypeVariables

Мы также можем использовать расширение ScopedTypeVariables [Haskell-wiki] , а затем реализовать его со ссылкой на переменную типа a:

{-# LANGUAGE <b>ScopedTypeVariables</b> #-}

getMaxBound :: <b>forall a .</b> Bounded a => a -> a
getMaxBound _ = maxBound <b>:: a</b>
...