Ricochet Challenge: Robust IO and working with different types of numbers in Haskell
You can reduce the fromIntegral spam like this:

ricochet :: (Integral a, Fractional b) =&gt; a -&gt; a -&gt; a -&gt; a -&gt; b -&gt; (Corner, a, b)
ricochet h w m n v
    = (c,b,fromIntegral d / v)

    where
    h' = h - m
    w' = w - n
    d  = lcm w' h'


The return value of functions like - and lcm is of the same type as their arguments, so the types of h' and the like can be inferred. You do need to write fromIntegral d / v because the compiler doesn't perform automatically the conversion required for the division operator. It's frequent to have these conversions functions at "type cast" boundaries.

But what if you want to keep the explicit signatures, for clarity? You can use "explicit forall" along with the ScopedTypeVariables extension, which allow you to say "this type here is the exact same type as the type in the top-level signature".

{-# LANGUAGE ScopedTypeVariables #-}
module Main
    ( Corner(..)
    , ricochet
    , main
    ) where

data Corner = UL | UR | LR | LL deriving (Show, Eq)

ricochet :: forall a b. (Integral a, Fractional b) 
         =&gt; a -&gt; a -&gt; a -&gt; a -&gt; b -&gt; (Corner, a, b)
ricochet h w m n v
    = (c,b,fromIntegral d / v)

    where
    h', w', d :: a
    h' = h - m
    w' = w - n
    d  = lcm w' h'