У меня проблема с системой типа Haskell. Это не первый раз, когда я сталкивался с ограничениями системы типов. Я опускаю детали своего проекта и использую упрощенный пример. Вот какой код:
-- Works
foo :: (Bounded a, Enum a) => a
foo = minBound
-- "ambiguous" constraint:
-- 'a' has no occurrences in type declaration
bar :: (Bounded a, Enum a) => Int
bar = fromEnum minBound
-- Too much information in return
-- but I can show haskell the appropriate type of 'min'
baz :: (Bounded a, Enum a) => (a, Int)
baz = let min = minBound
in (min, someFunction . fromEnum $ min)
-- Type constraint 'a' not ambiguous
-- (or at least that isn't the compiler error message)
-- but Haskell doesn't know which 'minBound' to use
barrer :: (Bounded a, Enum a) => a
barrer = let min = minBound -- <- min type is ambiguous
in toEnum . someFunction . fromEnum $ min
То, что я пытаюсь достичь, похоже на barrer
: во-первых, используйте значение minBound
, соответствующее типу a
и 'cast' его целому числу. В моем проекте я перехожу к преобразованию этого целого числа (чтобы избежать промежуточных арифметических переполнений при использовании типа a
) и "отбросить" их обратно, чтобы напечатать a
(после немного магии mod
). Как я могу указать Haskell на соответствующий тип minBound
? Возможно ли это?
Очевидным решением является добавление аннотации minBound :: a
. Это также исправило бы bar
. Проблема: переменная типа a
, по-видимому, выходит за рамки определения функции, так как Haskell освещает minBound :: a
до minBound a0
в сообщении об ошибке. Есть ли способ сделать этот тип аннотации?
Один плохой хак, который я использовал, заключался в том, чтобы ограничить тип вызова minBound
, включив его в возвращаемый тип функции, a la baz
. Это решение не является идеальным. Есть ли у кого-нибудь советы?