title: How do I make an argument a function of the type of another argument?
body: <p>I'm writing <a href="https://en.wikipedia.org/wiki/Minkowski%27s_question-mark_function" rel="nofollow noreferrer">Minkowski's question-mark function</a>, <code>?(<i>x</i>)</code>. The code looks like this:</p>
  <pre><code>-- Minkowski's question-mark function
  import Data.Ratio
  
  mink' :: (Ord a,RealFrac a) =&gt; a -&gt; a -&gt; a
  mink' toler x
    | toler &gt; 1 = x
    | x == 0 = x
    | x &lt; 0 = (-mink' toler (-x))
    | x &gt;= 1 = (mink' toler (x-1)) +1
    | otherwise = (2 ^^ (-intpart))* (2- mink' (toler/x^2) fracinvx )
    where
      invx=1/x
      intpart=floor invx
      fracinvx=invx-fromIntegral intpart
  
  -- mink :: (Num a,Floating a,RealFrac a) =&gt; a -&gt; a
  -- mink x = (mink' toler fracx) + intx
  --   where
  --     intx = fromIntegral (round x)
  --     fracx = x-intx
  --     (_,ex) = decodeFloat (1::a)
  --     toler = 2^^ex
  
  mink :: (Num a,RealFrac a) =&gt; a -&gt; a
  mink x = (mink' 0 fracx) + intx
    where
      intx = fromIntegral (round x)
      fracx = x-intx
  </code></pre>
  <p><code>mink x</code> works as long as <code>x</code> is Rational. If I run <code>mink 0.618034</code>, however, it hangs. I want to pass one ulp to <code>toler</code> if the type of <code>x</code> is <code>Floating</code>, but pass 0 to <code>toler</code> if the type of <code>x</code> is <code>Ratio</code>. A smaller <code>toler</code> works too, as long as it's greater than 0:</p>
  <pre><code>*Main&gt; mink' 1e-40 (((sqrt 5)-1)/2)
  0.6666666666683355
  </code></pre>
  <p>(<code>?(<i>1/φ</i>) == 2/3</code> exactly, but the function is very steep there.)
  How do I make <code>toler</code> depend on the type of <code>x</code>?</p>