Project Euler #3 in Haskell
You don't need to terminate the list of candidate factors.  Haskell, being a lazy language, deals with infinite lists just fine.

In Haskell, it is common to use pattern matching instead of if … then … else.

There is not much advantage to having your go helper take an Integer (Integer, Integer) rather than three Integers.

You are repeating the isDiv test in fullyDiv and go.  Instead of a fullyDiv function, you can just fold the retry logic into go itself.

The names x, y, and o are hard to follow.  I suggest maxPrime instead of x, and w instead of y (the mnemonic being the first character of wheel).

isDiv :: Integer -&gt; Integer -&gt; Bool
n `isDiv` k = n `mod` k == 0

maxPrimeFact :: Integer -&gt; Integer
maxPrimeFact n = go n 1 (2 : [3, 5..])
  where
    go 1 maxPrime _ = maxPrime
    go n maxPrime wheel@(w:ws)
      | n `isDiv` w = go (n `div` w) w wheel
      | otherwise   = go n maxPrime ws


But you should be able to rewrite it further by taking advantage of divMod.

maxPrimeFact :: Integer -&gt; Integer
maxPrimeFact n
  | n &lt; 2     = error ("Invalid n=" ++ (show n))
  | otherwise = go n 1 wheel
  where
    wheel = 2 : [3, 5..]
    go 1 largestPrimeFactor _ = largestPrimeFactor
    go n largestPrimeFactor (w:ws)
      | n `isDiv` w = go (n `div` w) w (w:ws)
      | otherwise   = go n largestPrimeFactor ws