Могу ли я в Haskell сделать числовые литералы не полиморфными по умолчанию?

Это, вероятно, невозможно, так как я уже проверил список всех расширений GHC, и этого там нет, но я подумал, что на всякий случай спрошу.

Есть ли способ сделать так, чтобы 2 имел тип Int (или Integer), а не обычный Num a => a?

(Причина, по которой мне нравится такое поведение, заключается в том, что оно делает сообщения об ошибках более четкими и делает более вероятным вывод типа (особенно с классами типов). безопасное" поведение будет менее явным)


person Owen    schedule 25.07.2011    source источник
comment
да, не делайте этого :) вывод типа обычно не так уж и плох. может быть, если вы опубликуете пример проблемы, люди помогут вам решить ее по-другому? вы можете установить значения по умолчанию через haskell.org/tutorial/numbers.html . вы также можете разработать прототипы типов функций верхнего уровня, установив для них значение f = undefined :: DesiredType и соответствующим образом очистив их.   -  person gatoatigrado    schedule 25.07.2011
comment
Полиморфные константы не мешают мне что-либо делать, но они делают сообщения об ошибках менее прямыми, обычно меняя a не может соответствовать ожидаемому типу... на no instance for.... Кроме того, значения по умолчанию обычно не позволяют вывести экземпляр для класса (и это похоже на взлом)   -  person Owen    schedule 25.07.2011


Ответы (2)


Существует (немного оскорбительный и неудобный) способ сделать это с помощью расширений GHC.

{-# LANGUAGE RebindableSyntax #-}

import qualified Prelude as P
import Prelude hiding (Num(..))

fromInteger :: Integer -> Integer
fromInteger = id

В GHCi:

> :set -XRebindableSyntax
> :t 2
2 :: Integer

С включенным расширением RebindindableSyntax GHC будет использовать любое fromInteger для обработки числовых литералов. Единственным ограничением является то, что он должен принимать аргумент типа Integer (на самом деле, даже это не требуется, но если это не так, вы получите ошибку типа из числовых литералов).

Обратите внимание, что, поскольку стандартный fromInteger является частью класса Num, вам может потребоваться кое-что изменить, чтобы все заработало правильно.

person C. A. McCann    schedule 25.07.2011
comment
Хм, пожалуй, лучше скрыть только fromInteger: import Prelude hiding (Num(fromInteger)) - person luqui; 25.07.2011
comment
Благодарю вас! Я проверил это, и он получил именно то поведение, которое я хочу... хотя это немного многословно (это также делает арифметику неудобной, но я все равно никогда не занимаюсь арифметикой). - person Owen; 25.07.2011
comment
@luqui: Возможно. Не уверен, что сразу придет в голову, если скрыть только то, что будет иметь странные результаты при использовании других функций в Num. - person C. A. McCann; 25.07.2011
comment
@Owen: Возможно, вы могли бы попробовать то, что предлагает Луки. Я был немного деспотичным, скрывая Num полностью, может быть, это и не нужно. - person C. A. McCann; 25.07.2011
comment
Да, предложение Луки работает; арифметика снова становится приятной. Но мне лично нравится избавляться от эстетического бремени, такого как добавление. Думаю, я буду продолжать прятать Num ;) - person Owen; 25.07.2011
comment
@Owen: Сокрытие Num также имеет то преимущество, что позволяет вам определять арифметические операторы независимо, вместо того, чтобы привязываться к плохому дизайну Num. - person C. A. McCann; 25.07.2011
comment
@Owen: Если ты не занимаешься арифметикой, то зачем тебе числа? - person yatima2975; 25.07.2011
comment
@ yatima2975 В основном я их просто перелопачиваю. Разбор арифметических выражений. - person Owen; 28.07.2011

Я думаю, что я должен добавить «по умолчанию ()» к этим ответам, хотя я думаю, что gatoatigrado упомянул об этом мимоходом. В стандарте Haskell 98 есть раздел 4.3.4, в котором в конечном итоге описывается, как изменить некоторые значения по умолчанию Num a => a. Неявный порядок невыполнения обязательств задается

 default (Integer, Double)

и может быть изменен, например. поставив

 default (Int)

or

 default ()

в исходном файле.

person Chris Kuklewicz    schedule 26.07.2011