title: Haskell: Can type variables be used within function definition?
body: <p>I have a problem relating to the Haskell type system. This is not the first time I have encountered the type system's limitations. I will omit my project details and use a simplified example. Here is some code:</p>
  
  <pre><code>-- Works
  foo :: (Bounded a, Enum a) =&gt; a
  foo = minBound
  
  -- "ambiguous" constraint:
  -- 'a' has no occurrences in type declaration
  bar :: (Bounded a, Enum a) =&gt; Int
  bar = fromEnum minBound
  
  -- Too much information in return
  -- but I can show haskell the appropriate type of 'min'
  baz :: (Bounded a, Enum a) =&gt; (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) =&gt; a
  barrer = let min = minBound -- &lt;- min's type is ambiguous
      in toEnum . someFunction . fromEnum $ min
  </code></pre>
  
  <p>What I am trying to achieve is similar to <code>barrer</code>: First, use the <code>minBound</code> value specific to type <code>a</code> and 'cast' it to an integer. In my project, I proceed to transform this integer (to avoid intermediate arithmetic overflows when using type <code>a</code>) and 'cast' them back to type <code>a</code> (after a bit of <code>mod</code> magic). How can I tell Haskell the appropriate type of <code>minBound</code>? Is it possible?</p>
  
  <p>The obvious solution is to add an annotation of <code>minBound :: a</code>. This would also fix <code>bar</code>. The problem: The type variable <code>a</code> seems to be out of scope in the function definition, as Haskell freshens <code>minBound :: a</code> to <code>minBound a0</code> in the error message. Is there a way to do this type of annotation?</p>
  
  <p>One bad hack I used was to constrain the type of the <code>minBound</code> call by including it in the function's return type, a la <code>baz</code>. This solution is not ideal. Does anyone have some advise?</p>